使用java流设置并集和交集

使用java流设置并集和交集,java,java-8,set,java-stream,Java,Java 8,Set,Java Stream,我目前有一个java程序,它使用嵌套for循环来计算一组整数的并集和交集。如何使用java并行流实现这一点?我目前拥有的代码如下 for(Set<Integer> x : listA) { for (Set<Integer> y : listB) { Set u = Sets.union(x,y); // Uses Guava library Set i = Sets.intersection(x,y); } } for(集合x:li

我目前有一个java程序,它使用嵌套for循环来计算一组整数的并集和交集。如何使用java并行流实现这一点?我目前拥有的代码如下

for(Set<Integer> x : listA) {
  for (Set<Integer> y : listB) {
       Set u = Sets.union(x,y); // Uses Guava library
       Set i = Sets.intersection(x,y);
  }
}
for(集合x:listA){
用于(集合y:listB){
Set u=Set.union(x,y);//使用番石榴库
集合i=集合交点(x,y);
}
}

由于listA和listB很大,我想加快速度。

联合不需要流,但可以将其用于交叉口,例如:

Set<Integer> setA = new HashSet<>(Arrays.asList(1,2,3));
Set<Integer> setB = new HashSet<>(Arrays.asList(2,3,4));
Set<Integer> union = new HashSet<>();
union.addAll(setA);
union.addAll(setB);

Set<Integer> intersection = setA.parallelStream()
        .filter(setB::contains)
        .collect(Collectors.toSet());

System.out.println("Union : " + union);
System.out.println("Intersection : " +intersection);

值得注意的是,您不必为联合和交叉使用流。有一个方法仅保留此集合中包含在指定集合中的元素:

Set<Integer> setA = new HashSet<>(Arrays.asList(1,2,3));
Set<Integer> setB = new HashSet<>(Arrays.asList(2,3,4));

setA.retainAll(setB);  // now setA has intersection
Set setA=newhashset(Arrays.asList(1,2,3));
setsetb=新的HashSet(Arrays.asList(2,3,4));
刚毛保留(后退);//现在setA有了交集
如果您确保y(和x)被排序,如类
树集
,以下使用特殊的合并(内部方法
addAllForTreeSet

Ý您可以使用并行流来保存与处理器数量相等的系数

listA.parallelStream().forEach(x -> {});
这是第二次优化

番石榴在过去几年中没有使用,它没有原始类型的集合吗

List<T> intersect = list1.stream()
                         .filter(list2::contains)
                         .collect(Collectors.toList());
List intersect=list1.stream()
.filter(列表2::包含)
.collect(Collectors.toList());
工会:

List<T> union = Stream.concat(list1.stream(), list2.stream())
                                    .distinct()
                                    .collect(Collectors.toList());  
List union=Stream.concat(list1.Stream(),list2.Stream())
.distinct()
.collect(Collectors.toList());

由于您没有对结果执行任何操作,因此删除整个代码是最快的解决方案。否则,您应该包括应该并行运行的实际操作。@Holger难道不可能使联合操作本身并行吗?没有显著的性能改进。并行执行
并集
交集
时,性能很可能会变差。正如你自己所说,
listA
listB
都很大,所以你应该专注于并行处理这些列表。并行化并不容易。也许这种方法已经足够好了:@Holger感谢您的评论
如何使用java并行流来实现这一点?
这不是问题吗?@DarshanMehta嗯,更新的答案将两个嵌套的
for
循环替换为两个嵌套的
forEach
流调用。。。我不确定这将如何执行better@BackSlash好吧,在不知道OP想要对结果做什么的情况下,没有更好的选择。这取决于特定的值分布
BitSet
是否产生更好的性能。对于许多实际用例,它确实如此。但是,考虑一个只包含零和“代码>整数”的集合。Max值< /代码>…@ Joop-EGGEN,如果你不介意的话,你能给我演示一下如何将一组整数转换成比特集的例子吗?假设我的整数范围是从0到15000@Koba
BitSet bs=set.stream().collect(BitSet::new,BitSet::set,BitSet::or)
Set Set=bs.stream().boxed().collect(Collectors.toSet())另一个方向。@Holger谢谢,你比我快到了,还有streams,嗯。@Holger再次感谢你的帮助。我将很快尝试。这应该是一个评论。问题是:如何使用并行流而不是嵌套循环计算并集和交集你不是在回答这个问题,而是在建议如何避免使用外部库来完成这项工作。
listA.parallelStream().forEach(x -> {});
List<T> intersect = list1.stream()
                         .filter(list2::contains)
                         .collect(Collectors.toList());
List<T> union = Stream.concat(list1.stream(), list2.stream())
                                    .distinct()
                                    .collect(Collectors.toList());