Eu diria que essas respostas perdem um truque.
Bloch, em seu Java efetivo essencial, maravilhoso e conciso , diz, no item 47, o título "Conheça e use as bibliotecas", "Para resumir, não reinvente a roda". E ele dá várias razões muito claras por que não.
Existem algumas respostas aqui que sugerem métodos da CollectionUtils
biblioteca Apache Commons Collections, mas nenhuma encontrou a maneira mais bonita e elegante de responder a essa pergunta :
Collection<Object> culprits = CollectionUtils.disjunction( list1, list2 );
if( ! culprits.isEmpty() ){
// ... do something with the culprits, i.e. elements which are not common
}
Culpados : ou seja, os elementos que não são comuns a ambos Lists
. Determinar a quais culpados pertencem list1
e a qual list2
é relativamente simples usar CollectionUtils.intersection( list1, culprits )
e CollectionUtils.intersection( list2, culprits )
.
No entanto, ele tende a desmoronar em casos como {"a", "a", "b"} disjunction
com {"a", "b", "b"} ... exceto que isso não é uma falha do software, mas inerente à natureza das sutilezas / ambiguidades da tarefa desejada.
Você sempre pode examinar o código fonte (l. 287) para uma tarefa como essa, produzida pelos engenheiros da Apache. Um benefício do uso de seu código é que ele foi testado e testado exaustivamente, com muitos casos extremos e dicas antecipadas e resolvidas. Você pode copiar e ajustar esse código para o conteúdo do seu coração, se necessário.
NB: No começo, fiquei desapontado por nenhum dos CollectionUtils
métodos fornecer uma versão sobrecarregada, permitindo que você imponha a sua própria Comparator
(para que você possa redefinir equals
para atender às suas finalidades).
Mas a partir das coleções4 4.0, há uma nova classe, Equator
que "determina a igualdade entre objetos do tipo T". Ao examinar o código-fonte de collections4 CollectionUtils.java, eles parecem estar usando isso com alguns métodos, mas, pelo que sei, isso não se aplica aos métodos na parte superior do arquivo, usando a CardinalityHelper
classe ... inclua disjunction
e intersection
.
Suponho que o pessoal do Apache ainda não tenha resolvido isso porque não é trivial: você teria que criar algo como uma classe "AbstractEquatingCollection", que, em vez de usar os métodos equals
e hashCode
métodos inerentes aos seus elementos, teria que usá-los de Equator
todos os métodos básicos, como add
, contains
etc. Nota: quando você olha para o código-fonte, AbstractCollection
não implementa add
nem suas subclasses abstratas como AbstractSet
... você precisa esperar até as classes concretas como HashSet
e ArrayList
antes add
é implementado. Bastante dor de cabeça.
Enquanto isso, assista a este espaço, suponho. A solução provisória óbvia seria agrupar todos os seus elementos em uma classe de wrapper personalizada que usa equals
e hashCode
implementar o tipo de igualdade que você deseja ... e então manipular Collections
esses objetos de wrapper.