Java Stream Reduce对象数组

时间:2019-06-18 13:53:10

标签: java java-8 java-stream reduce

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

List<Object[2]>

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

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

result[0] = multiplication of all object[0]
result[1] = concatenation of all object[1]

3 个答案:

答案 0 :(得分: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
}

答案 1 :(得分: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}
    ));

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

This answer显示了teeing收集器的一个版本,该版本在Java 8下工作。

答案 2 :(得分:8)

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

这是这里:List<Object[2]>感觉很不对劲。

您为什么不使用类似List<Pair<Integer, String>>的东西?!

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

答案代码变成:

.reduce(p1, p2 -> new Pair<>(p1.first * p2.first, p1.second + p2.second))

严重的是:它首先使用Object[] ...,最后您切换到ruby,这是因为动态键入!