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<Object[2]>
感觉太不对了。
你为什么不使用类似的东西:List<Pair<Integer, String>>
?!
换句话说:不要轻易放弃类型信息。不要滥用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 对象数组的主要内容,如果未能解决你的问题,请参考以下文章