Java Stream Reduce对象数组

Noo*_*oor 9 java reduce java-8 java-stream

我有2个对象的数组的列表:

List<Object[2]>
Run Code Online (Sandbox Code Playgroud)

其中object [0]是一个整数,而object [1]是一个字符串。

我如何流式列表并在每个对象上应用不同的功能?这样,结果将是一个具有以下内容的数组:

result[0] = multiplication of all object[0]
result[1] = concatenation of all object[1]
Run Code Online (Sandbox Code Playgroud)

Vin*_*sau 11

您可以使用以下方法实现此目的reduce()

public void testStacko() {
    List<Object[]> list = new ArrayList<>();
    list.add(new Object[] {1, "foo"});
    list.add(new Object[] {6, "|bar"});
    list.add(new Object[] {15, "|baz"});
    Object[] array = list.stream()
                         .reduce(
                                  (obj1, obj2) -> 
                                   new Object[] {(int) obj1[0] * (int) obj2[0], 
                                                 (String) obj1[1] + (String) obj2[1]
                                                }
                                )
                         .get();
    System.out.println(array[0]); // 90
    System.out.println(array[1]); // foo|bar|baz
}
Run Code Online (Sandbox Code Playgroud)

  • 但这对于较大的列表而言效率不高。 (5认同)

Hol*_*ger 10

使用JDK-12,您可以使用

Object[] array = list.stream()
    .collect(Collectors.teeing(
        Collectors.reducing(1, a -> (Integer)a[0], (a,b) -> a * b),
        Collectors.mapping(a -> (String)a[1], Collectors.joining()),
        (i,s) -> new Object[] { i, s}
    ));
Run Code Online (Sandbox Code Playgroud)

但您确实应该重新考虑您的数据结构。

此答案显示了teeing可以在Java 8下运行的收集器的版本。

  • @GhostCat我一直想起一个T连接器或Unix命令`tee`。不知道“准备”这个词是否早于此。 (2认同)

Gho*_*ica 8

您已经获得了很好的技术答案,因此让我们添加一个独特的非答案。

在这里:List<Object[2]>感觉太不对了。

您为什么不使用以下内容List<Pair<Integer, String>>

换句话说:不要轻易放弃类型信息。不要误用Object[]为无类型的容器来填充已经键入的内容。Java是一种静态编译语言。含义:不要抗拒泛型和严格类型的作用,而应与它们顺其自然。

答案代码变成:

.reduce(p1, p2 -> new Pair<>(p1.first * p2.first, p1.second + p2.second))
Run Code Online (Sandbox Code Playgroud)

认真地讲:它从使用Object[]... 开始,直到您切换到ruby才结束,这是因为动态键入!

  • @Noor然后,任何使用名称和类型定义不同字段的类类型都比必须从其位置猜测其含义的不同类型元素的数组更好。 (3认同)