我目前有一个Java程序,该程序使用嵌套的for循环来计算一组整数列表的并集和交集。如何使用java parallel 流执行此操作?我目前拥有的代码如下
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);
}
}
由于listA和listB很大,所以我想加快速度。
答案 0 :(得分:2)
您不需要流来进行联合,但是,您可以将其用于交集,例如:
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);
更新
以上代码使用Java的本机库和streams
查找交集和并集。但是,如果您有一组集合,则可以将上述代码包装在函数中,然后从stream
进行调用,以迭代两个列表,例如:
private static void unionAndIntersection(Set<Integer> setA, Set<Integer> setB) {
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);
}
public static void main(String[] args){
List<Set<Integer>> listA = new ArrayList<>();
List<Set<Integer>> listB = new ArrayList<>();
listA.stream()
.forEach(a -> {
listB.stream()
.forEach(b -> unionAndIntersection(a, b));
});
}
答案 1 :(得分:2)
如果确保像类TreeSet
那样对y(和x)进行了排序,则以下代码将使用特殊的合并(内部方法addAllForTreeSet
)。
for (Set<Integer> x : listA) {
for (SortedSet<Integer> y : listB) {
SortedSet<Integer> u = new TreeSet(x);
u.addAll(y);
SortedSet<Integer> i = new TreeSet(x);
i.retainAll(y);
}
}
我不确定这实际上是否更快。
更好的是,如果整数不是太通配(限于10_000)。如果这些值是非负数,则可以立即使用BitSet
代替Set<Integer>
。
这是无与伦比的。使用可能的容量(例如10_000)的BitSet构造函数。
for (BitSet x : listA) {
for (BitSet y : listB) {
BitSet u = x.clone();
u.or(y);
BitSet i = x.clone();
i.and(y);
}
}
Ý您可能会使用并行流来节省等于处理器数量的因数。
listA.parallelStream().forEach(x -> {});
这是次要的优化。
我过去几年没有使用过的番石榴,它没有原始类型int
的集合吗?
答案 2 :(得分:1)
值得注意的是,您不必将流用于联合和相交。 retainAll
方法仅保留此集合中包含在指定集合中的元素:
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
答案 3 :(得分:1)
交叉点:
List<T> intersect = list1.stream()
.filter(list2::contains)
.collect(Collectors.toList());
联盟:
List<T> union = Stream.concat(list1.stream(), list2.stream())
.distinct()
.collect(Collectors.toList());