Я б сказав, що ці відповіді пропускають хитрість.
Блох, у своїй важливій, чудовій, стислій Ефективній Java , у пункті 47 зазначає заголовок «Знай і користуйся бібліотеками», «Підсумувати, не винаходити колесо». І він наводить кілька дуже чітких причин, чому ні.
Тут є кілька відповідей, які пропонують методи з CollectionUtils
бібліотеки колекцій Apache Commons, але жоден не знайшов найкрасивішого, елегантного способу відповісти на це питання :
Collection<Object> culprits = CollectionUtils.disjunction( list1, list2 );
if( ! culprits.isEmpty() ){
// ... do something with the culprits, i.e. elements which are not common
}
Винуватці : тобто елементи, які не є спільними для обох Lists
. Визначення, до яких винуватців належать, list1
а до list2
яких відносно просте використання CollectionUtils.intersection( list1, culprits )
та CollectionUtils.intersection( list2, culprits )
.
Однак вона, як правило, розпадається на випадки, як {"a", "a", "b"} disjunction
з {"a", "b", "b"} ... за винятком цього не є збоєм програмного забезпечення, але притаманні природі тонкощів / неоднозначності бажаного завдання.
Ви завжди можете вивчити вихідний код (л. 287) для подібного завдання, виробленого інженерами Apache. Однією з переваг використання їх коду є те, що він буде ретельно випробуваний і протестований, з багатьма крайніми справами та готчами передбачається і вирішується. Ви можете скопіювати і підкоригувати цей код до вмісту серця, якщо це буде потрібно.
NB: Спочатку я був розчарований, що жоден із CollectionUtils
методів не забезпечує перевантажену версію, що дозволяє вам нав'язувати своє Comparator
(щоб ви могли переосмислитись equals
відповідно до своїх цілей).
Але з collection4 4.0 з'явився новий клас, Equator
який "визначає рівність між об'єктами типу T". Перевіряючи вихідний код collection4 CollectionUtils.java, вони, здається, використовують це деякими методами, але, наскільки я можу це зробити, це не стосується методів у верхній частині файлу, використовуючи CardinalityHelper
клас ... який включати disjunction
і intersection
.
Я гадаю, що люди Apache ще не вирішили цього питання, оскільки це нетривіально: вам доведеться створити щось на кшталт класу "AbstractEquatingCollection", який замість того, щоб використовувати притаманні його елементи equals
та hashCode
методи, замість цього повинен був би використовувати ці з Equator
усіх основних методів, таких як add
, contains
і т.д. NB насправді , коли ви подивіться на вихідний код, AbstractCollection
не реалізує add
, ні робити свої абстрактні підкласи , такі як AbstractSet
... ви повинні чекати , поки класи бетону , такі як HashSet
і ArrayList
до того add
реалізується. Досить болить голова.
Тим часом спостерігаю за цим простором, я думаю. Очевидним тимчасовим рішенням було б обернути всі ваші елементи в замовлений клас обгортки, який використовує equals
та hashCode
реалізувати потрібну рівність ... потім маніпулювати Collections
цими об'єктами обгортки.