Direi che a queste risposte manca un trucco.
Bloch, nel suo essenziale, meraviglioso, conciso Effective Java , dice, al punto 47, il titolo "Conosci e usa le librerie", "Per riassumere, non reinventare la ruota". E fornisce diverse ragioni molto chiare perché no.
Ci sono alcune risposte qui che suggeriscono metodi CollectionUtilsnella libreria delle Collezioni di Apache Commons, ma nessuna ha individuato il modo più bello ed elegante per rispondere a questa domanda :
Collection<Object> culprits = CollectionUtils.disjunction( list1, list2 );
if( ! culprits.isEmpty() ){
// ... do something with the culprits, i.e. elements which are not common
}
Culprits : cioè gli elementi che non sono comuni ad entrambi Lists. Determinare a quali colpevoli appartengono list1e a quali list2è relativamente semplice usando CollectionUtils.intersection( list1, culprits )e CollectionUtils.intersection( list2, culprits ).
Tuttavia tende a sfaldarsi in casi come {"a", "a", "b"} disjunctioncon {"a", "b", "b"} ... tranne per il fatto che non si tratta di un errore del software, ma inerente alla natura delle sottigliezze / ambiguità dell'attività desiderata.
Puoi sempre esaminare il codice sorgente (l. 287) per un'attività come questa, prodotta dagli ingegneri Apache. Uno dei vantaggi dell'utilizzo del loro codice è che sarà stato accuratamente testato e testato, con molti casi limite e aspetti previsti e trattati. Puoi copiare e modificare questo codice in base al tuo cuore, se necessario.
NB All'inizio ero deluso dal fatto che nessuno dei CollectionUtilsmetodi fornisse una versione sovraccarica che ti consentisse di imporre il tuo Comparator(in modo da poter ridefinire equalsin base ai tuoi scopi).
Ma da collection4 4.0 esiste una nuova classe, Equatorche "determina l'uguaglianza tra oggetti di tipo T". Esaminando il codice sorgente di collection4 CollectionUtils.java sembrano usarlo con alcuni metodi, ma per quanto ne so non è applicabile ai metodi nella parte superiore del file, usando la CardinalityHelperclasse ... che include disjunctione intersection.
Suppongo che la gente di Apache non si sia ancora occupata di questo perché non è banale: dovresti creare qualcosa di simile a una classe "AbstractEquatingCollection", che invece di usare i suoi elementi intrinseci equalse i hashCodemetodi dovrebbero invece usare quelli di Equatorper tutti i metodi di base, come add, containsecc. NB, infatti, quando si guarda il codice sorgente, AbstractCollectionnon si implementa add, né si fanno le sue sottoclassi astratte come AbstractSet... bisogna aspettare fino alle classi concrete come HashSete ArrayListprima addè implementato. Abbastanza mal di testa.
Nel frattempo, guarda questo spazio, suppongo. L'ovvia soluzione provvisoria sarebbe quella di avvolgere tutti i tuoi elementi in una classe wrapper su misura che utilizza equalse hashCodeimplementare il tipo di uguaglianza che desideri ... quindi manipolare Collectionsquesti oggetti wrapper.