Java Stream Reduce 对象数组

Posted

技术标签:

【中文标题】Java Stream Reduce 对象数组【英文标题】:Java Stream Reduce of array of objects 【发布时间】:2019-11-01 04:44:02 【问题描述】:

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

List<Object[2]>

object[0] 是 Integer,object[1] 是 String。

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

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

【问题讨论】:

【参考方案1】:

您可以通过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

【讨论】:

但是对于较大的列表来说效率相当低。【参考方案2】:

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

这里:List&lt;Object[2]&gt; 感觉太不对了。

你为什么不使用类似的东西:List&lt;Pair&lt;Integer, String&gt;&gt;?!

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

而答案代码变成:

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

说真的:它从使用Object[] 开始...结束于你切换到 ruby​​ 因为动态类型!

【讨论】:

我同意,一对会更好。 因为我的列表有超过 2 个对象。我以 2 个对象列表为例。在 2 个对象的情况下,Pair 肯定更好。 @Holger 同意。我现在正在研究 POC,并且将有一个包含所有这些对象的类。我只是想知道如何对流对象执行不同的功能。【参考方案3】:

有了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 显示了在 Java 8 下工作的 teeing 收集器版本。

【讨论】:

@GhostCat 我一直想到一个 T 连接器或 Unix 命令tee。不知道“发球”这个词是否早于此。

以上是关于Java Stream Reduce 对象数组的主要内容,如果未能解决你的问题,请参考以下文章

java8的stream().mapToInt()啥意思?

java8 如何在stream之后判断使用哪个方法

Java基础之Stream流(JDK1.8新特性)

JS去除数组对象相同的数据

获取单列集合,双列集合,数组的Stream流对象以及简单操作

JavaScript 基于reduce方法实现数组内对象的同属性运算