【发布时间】:2014-07-30 22:27:53
【问题描述】:
我遇到这种情况,Java 8 Streams API 似乎会有所帮助,但我不完全确定它会如何。
从具有不同元素类型的两个集合中,我想构建第三个集合,其元素是两个集合中所有可能的元素对。基本上:
两种不同的元素类型...
public class A {}
public class B {}
一对“A”和“B”。
public class Pair {
private A a;
private B b;
public Pair(A a, B b){
this a = a;
this b = b;
}
}
使用旧式java.util.Collection API 制作的“组合”:
public Collection<Pair> combine(Collection<A> as, Collection<B> bs){
Collection<Pair> pairs = new ArrayList();
foreach(A a: as){
foreach(B b: bs){
Pair pair = new Pair(a,b);
pairs.add(pair);
}
}
return pairs;
}
结果对集合中的顺序并不重要。因此,可以并行创建 Pair 的每个实例并将其添加到结果集合中。我怎样才能做到这一点?
我自己能想到的最好办法就是使用 foreach 的 Streams 版本:
as.foreach(
a -> {
bs.foreach(
b -> {
Pair pair = new Pair(a,b);
pairs.add(pair);
}
}
);
为了简化起见,这个例子是微不足道的。 Pair 类是将两个元素处理为第三个元素(即java.util.function.BiFunction)的示例,并将它们添加到Collection 只是可变归约的一个示例。
有没有更优雅的方法来做到这一点?或者更可取,在效率方面以更有利可图的方式?类似的东西
BiFunction<A,B,Pair> combinator = Pair::new; //or any other function f(a,b)=c;
Stream<Pair> pairStream =
Streams.unknownElegantMethod(as.stream(), bs.stream(), combinator);
【问题讨论】:
-
与问题无关,但不是
(a,b) -> {return new Pair(a,b)}; usePair::new. And for the question, stream are usable once. And you Java code shows that you are using a stream more than one time (the one onbs`)。 -
关于
Pair:new的好点,我已经更新了这个问题。第二点是错误的,因为bs是Collection,而不是流。 -
不,我明白了。我的意思是当你用完一个流时,你就不能再使用它了。因此,当且仅当您想要所有可能的 (A, B) 对时,解决方案不能或永远不会像
Stream<Pair> pairStream = Streams.unknownElegantMethod(as.stream(), bs.stream(), combinator);那样。使用flatMap(如答案)或foreach(如您的代码)是唯一的解决方案。
标签: java lambda java-8 java-stream