我很难为这篇文章起个名字。
基本上,我有两组:叫A
和B
。
我想执行以下操作(\
代表除外):
C = A\B
loop through C;
D = B\A
loop through D;
loop through B;
我第一次成功的尝试是:
// B and A are lists
List<T> C = new LinkedList<>(A);
C.removeAll(B);
for (T other : C)
operationX(other);
List<T> D = new LinkedList<>(B);
D.removeAll(A);
for (T other : D)
operationY(other);
for (T other : B)
operationZ(other);
但这似乎太慢了。该功能每秒被调用数百次,并且集合可以包含数百个对象。
实现这一目标的有效方法是什么样的?
答案 0 :(得分:3)
如果您只打算遍历C
,则根本不需要创建它。您可以简单地过滤掉{{1}中包含的A
中的每个元素,然后对每个过滤后的元素调用B
:
operationX
假设Set<T> bSet = new HashSet<>(B);
A.stream()
.filter(a -> !bSet.contains(a))
.forEach(this::operationX);
中可能存在重复元素,并且所有重复项都需要调用B
,那么我们可以使用以下内容:
operationY
如果即使存在重复,Set<T> aSet = new HashSet<>(A);
B.stream()
.filter(b -> !aSet.contains(b))
.forEach(this::operationY);
B.forEach(this::operationZ);
中的每个元素只需要为operationY
调用一次,那么我建议改用以下代码:
B
答案 1 :(得分:0)
要计算C = A \ B,您可以先从B构建一个HashSet,然后在A上进行迭代,然后将所有元素添加到散列集中不存在的最初为空的集合C中。
此外,如果您经常对一个大列表进行迭代,则应尽可能使用ArrayList而不是LinkedList,因为由于发生许多高速缓存未命中,对大型链表进行迭代的速度确实很慢。