Сравните два списка обновлений, удалений и дополнений

Простой вопрос.

У меня есть новый список и старый список. В Java есть стандартный способ/библиотека, который позволяет мне сравнивать эти два списка и определять, какие элементы были обновлены/удалены или совершенно новые? Например. Я должен добавить три списка - Удаленные элементы (элементы старые, но не новые), Обновленные элементы (элементы в обоих), Новые элементы (элементы в новом, а не в старом).

Я мог бы написать это сам, но задавался вопросом, есть ли стандартный способ сделать это.

Объекты в реализации списка равны правильно.

Ответы

Ответ 1

Нет стандартного способа извините. Вы можете сделать это довольно легко со стандартным JDK, не прибегая к добавлению зависимости от Apache Commons (как другие предложили). Предполагая, что ваши списки List<T> экземпляры:

List<T> oldList = ...
List<T> newList= ...

List<T> removed = new ArrayList<T>(oldList);
removed.removeAll(newList);

List<T> same = new ArrayList<T>(oldList);
same.retainAll(newList);

List<T> added = new ArrayList<T>(newList);
added.removeAll(oldList);

Ответ 2

В стандартных библиотеках ничего нет.

Однако класс Apache Commons CollectionUtils предоставляет вам эту функцию с помощью методов пересечения и вычитания:

Collection<T> old = ...;
Collection<T> neww = ...;

Collection<T> deleted = (Collection<T>)CollectionUtils.subtract(old, new);
Collection<T> updated = (Collection<T>)CollectionUtils.intersection(old, new);
Collection<T> newResult = (Collection<T>)CollectionUtils.subtract(new, old);

(Вам нужны (непроверенные) роли, потому что CollectionUtils не генерируется.)

Ответ 3

Я бы использовал Apache CollectionUtils и использовал объединение (элементы в обоих) и функции дизъюнкции (измените порядок, чтобы получить тот или иной).

В идеале вы должны сделать один проход по всем элементам вместо 3, но если это не ваше узкое место, я бы не стал беспокоиться об эффективности прямо сейчас.

Ответ 4

Лично я считаю, что единственный разумный способ объяснить разницу между двумя списками заключается в полномасштабном алгоритме diff (например, в команде unix diff).

Устанавливает, однако, гораздо более простой рассказ. Google Collections предоставляет метод Sets.difference(Set, Set), а также объединение и пересечение.

Ответ 5

Я думаю, вы можете это сделать со стандартной java-библиотекой. Взгляните на следующие методы java.util.Collection:

keepAll (сборник c)

Сохраняет только элементы в этом которые содержатся в указанная коллекция (необязательно операция). Другими словами, удаляет из этой коллекции все ее элементы, которые не содержатся в указанной коллекции.

removeAll (коллекция c)

Удаляет все элементы коллекции которые также содержатся в указанная коллекция (необязательно операция). После того, как этот вызов вернется, эта коллекция не будет содержать элементы, общие с указанными коллекция.

Ответ 6

Если есть стандартный способ, я не знаю...
Я посмотрел на Collections, но видел только disjoint() (это уже информация...) и indexOfSubList() (не уверен, что он вообще полезен).
Я также посмотрел на Коллекции Google, и если есть, по-видимому, не такой объект, есть некоторые полезные инструменты, такие как Collections2 функция filter(), которая может помочь, если вы сделаете правильный Predicate.

[EDIT] Я пропустил removeAll и удержал все методы Collection... Я не удаляю этот ответ, даже если немного жалкий, так как он каким-то образом дополняет другие ответы... (я думаю, Google Collections по крайней мере, стоит упомянуть!)