Цикл и работа между наборами / списками - PullRequest
0 голосов
/ 20 октября 2018

Мне было трудно придумать название для этого поста.По сути, у меня есть два набора: назовем это 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);

Но это кажется слишком медленным.Предполагается, что эта функция вызывается сотни раз в секунду, и наборы могут содержать сотни объектов.

Как бы выглядел эффективный способ достижения этого?

Ответы [ 2 ]

0 голосов
/ 20 октября 2018

Чтобы вычислить C = A \ B, вы можете сначала построить HashSet из B, а затем выполнить итерацию по A и добавить все элементы в изначально пустой набор C, которых нет в хэш-наборе.

Также,если вы часто перебираете большой список, вы должны использовать ArrayList вместо LinkedList, если это возможно, потому что перебор больших связанных списков очень медленный из-за большого количества пропусков кэша.

0 голосов
/ 20 октября 2018

Нет необходимости вообще создавать C, если вы просто планируете итерацию по нему.Вы можете просто отфильтровать каждый элемент в 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, даже если дубликатысуществует, тогда я рекомендую использовать приведенный ниже код:

bSet.removeAll(A);
bSet.forEach(this::operationY);
B.forEach(this::operationZ);
...