什么是Java 8个流API相当于LINQ加入? [英] What is the Java 8 Stream API equivalent for LINQ Join?

查看:400
本文介绍了什么是Java 8个流API相当于LINQ加入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#/。NET有可能加盟的IEnumerable序列与在SQL扩展方法Enumerable.JoinJOIN ... ON'的方式。

In C#/.Net it is possible to join IEnumerable sequences with the extension method Enumerable.Join in a SQL 'JOIN ... ON' way.

有没有在Java中8(流API)相似的地方?或者有什么是模拟Enumerable.Join最好的方法是什么?

Is there something similar in Java 8 (Stream API)? Or what is the best way to simulate Enumerable.Join?

请参阅: https://msdn.microsoft.com/en -us /库/ bb534675%28V = VS.100%29.aspx

推荐答案

我还没有发现任何现有的相当,但低于方法应该工作:

I haven't found any existing equivalent, but the below method should work:

public static <Outer, Inner, Key, Result> Stream<Result> join(
        Stream<Outer> outer, Stream<Inner> inner,
        Function<Outer, Key> outerKeyFunc,
        Function<Inner, Key> innerKeyFunc,
        BiFunction<Outer, Inner, Result> resultFunc) {

    //Collect the Inner values into a list as we'll need them repeatedly
    List<Inner> innerList = inner.collect(Collectors.toList());

    //matches will store the matches between inner and outer
    final Map<Outer, List<Inner>> matches = new HashMap<>();

    //results will be used to collect the results in
    final List<Result> results = new ArrayList<>();


    outer.forEach(o -> innerList
            .stream()
            //Filter to get those Inners for which the Key equals the Key of this Outer
            .filter(i -> innerKeyFunc.apply(i).equals(outerKeyFunc.apply(o)))
            .forEach(i -> {
                if (matches.containsKey(o)) {
                    //This Outer already had matches, so add this Inner to the List
                    matches.get(o).add(i);
                } else {
                    //This is the first Inner to match this Outer, so create a List
                    List<Inner> list = new ArrayList<>();
                    list.add(i);
                    matches.put(o, list);
                }
            }));

    matches.forEach((out, in) -> in.stream()
            //Map each (Outer, Inner) pair to the appropriate Result...
            .map(i -> resultFunc.apply(out, i))
            //...and collect them
            .forEach(res -> results.add(res)));

    //Return the result as a Stream, like the .NET method does (IEnumerable)
    return results.stream();
}

我只用下面的输入做的code简短的测试:

I only did a brief test of the code using the following inputs:

public static void main(String[] args) {
    Stream<String> strings = Arrays.asList("a", "b", "c", "e", "f", "d").stream();
    Stream<Integer> ints = Arrays.asList(1, 2, 3, 6, 5, 4).stream();
    Stream<String> results = join(strings, ints, 
            Function.identity(),
            str    -> Integer.parseInt(str, 16) - 9, 
            (o, i) -> "Outer: " + o + ", Inner: " + i);
    results.forEach(r -> System.out.println(r));
}

  • INT 是自己的钥匙,所以没有转化
  • 字符串映射到 INT 根据自己的十六进制值S - 9
  • (元素相匹配,如果 INT 值相等时,按默认值)
  • 配对放入一个字符串
    • The ints are their own keys, so no transformation
    • The Strings are mapped to ints according to their hex value - 9
    • (The elements match if the int values are equal, as per default)
    • Matching pairs are put into a String
    • 下面的(正确的)打印结果:

      The following (correct) results are printed:

      Outer: a, Inner: 1
      Outer: b, Inner: 2
      Outer: c, Inner: 3
      Outer: d, Inner: 4
      Outer: e, Inner: 5
      Outer: f, Inner: 6
      

      更深入的测试将是必要的,当然,但我相信这个实现是正确的。这也许可以更有效的为好,我很开放的建议。

      More in-depth testing will be needed, of course, but I believe this implementation to be correct. It could probably be more efficient as well, I'm open to suggestions.

      这篇关于什么是Java 8个流API相当于LINQ加入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆