2009-11-03 10 views
13

Domanda semplice.Confronta due elenchi per aggiornamenti, eliminazioni e aggiunte

Ho una nuova lista e una vecchia lista. In Java c'è un modo standard/libreria che mi permette di confrontare questi due elenchi e determinare quali articoli sono stati aggiornati/cancellati o sono completamente nuovi? Per esempio. Dovrei finire con tre elenchi: elementi eliminati (elementi vecchi ma non nuovi), articoli aggiornati (elementi in entrambi), nuovi elementi (elementi nuovi e non vecchi).

Potrei scrivere da solo, ma mi chiedevo se esiste un modo standard per farlo.

Gli oggetti nella lista implementano correttamente.

+0

Sei preoccupato per l'ordine della lista? Ad esempio, le soluzioni suggerite finora che coinvolgono retainAll/removeAll non tratteranno la situazione in cui il nuovo elenco contiene gli stessi elementi del vecchio elenco, anche se in un ordine diverso; per esempio. {"foo", "bar"} vs {"bar", "foo"}. – Adamski

+0

Fintanto che il metodo equals è implementato corret- tamente, non vedo perché l'ordine dovrebbe influenzare removeAll ecc. Certamente non suggerisce in javadoc: Rimuove da questo elenco tutti gli elementi contenuti nella collezione specificata (operazione opzionale). – Pablojim

risposta

31

Nessuno standard molto dispiaciuto. Puoi farlo abbastanza facilmente con il JDK standard senza ricorrere all'aggiunta di una dipendenza da Apache Commons (come altri hanno suggerito) comunque. Assumendo che il liste sono List<T> casi:

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); 
+0

+1 - sì, molto meglio del mio. –

+1

Sfortunatamente questo è leggermente sbagliato ... removeAll e simili operano nella lista passata e restituiscono un valore booleano. In modo che non verrà compilato. Deve essere: Elenco aggiunto = nuovo ArrayList (nuova lista); added.removeAll (oldList); ecc ... Quindi ci potrebbe essere un caso per i metodi di apache comuni dopotutto ... – Pablojim

+0

@Pablojim: giusto, grazie. Fisso. – cletus

3

Vorrei utilizzare Apache CollectionUtils e utilizzare l'unione (voci in entrambe) e le funzioni di disgiunzione (modificare l'ordine per ottenere uno o l'altro).

Idealmente si farebbe un passaggio su tutti gli elementi invece di 3, ma se questo non è il collo di bottiglia, non mi preoccuperei per l'efficienza in questo momento.

7

Non c'è niente nelle librerie standard.

Tuttavia il CollectionUtils classe Apache Commons ti dà questa funzionalità con l'incrocio e sottrarre metodi:

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); 

(È necessario il (incontrollato) getta perché CollectionUtils non è generified.)

1

Penso che si può raggiungere questo obiettivo con la libreria Java Standard troppo. Date un'occhiata ai seguenti metodi di java.util.Collection:

retainAll (Collection c)

conserva solo gli elementi di questa collezione che sono contenuti nella raccolta specificato (opzionale di funzionamento) . In altre parole, rimuove da questa raccolta tutti gli elementi che non sono contenuti nella raccolta specificata .

removeAll (Collection c)

rimuove tutti gli elementi di questa collezione anch'esse contenute nel insieme specificato ( operazione facoltativa). Dopo questa chiamata restituisce, questa raccolta non conterrà gli elementi in comune con la raccolta specificata .

0

Se c'è un modo standard, non so che ...
ho guardato Collections ma solo visto disgiunto() (che è già un'informazione ...) e indexOfSubList() (non è sicuro se è utile a tutti).
Ho anche guardato a Google Collections e se c'è, apparentemente, non è una tale funzione, ci sono alcuni strumenti utili lì, come la funzione filter() di Collections2 che può aiutare se si realizza un Predicato corretto.

[EDIT] Mi mancano i metodi removeAll e retainAll di Collection ... Non elimino questa risposta, anche se un po 'patetica, in quanto in qualche modo complementare alle altre risposte ... (Penso che Google Collections è almeno degno di nota!)

2

Personalmente, credo che l'unico modo ragionevole per spiegare la differenza tra due liste sia con un algoritmo diff completo (come quello del comando diff unix).

Set, tuttavia, sono una storia molto più semplice. Google Collections fornisce un metodo Sets.difference(Set, Set) e unione e intersezione.