2010-11-03 23 views
7

Ho due raccolte in una classe Java. La prima raccolta contiene dati precedenti, la seconda contiene dati aggiornati dalla raccolta precedente.Confronto di due raccolte in Java

Vorrei confrontare le due raccolte ma non sono sicuro del modo migliore per implementarlo in modo efficiente. Le raccolte conterranno la stessa quantità di articoli.

Basandomi sul fatto che carType è lo stesso in ogni raccolta, voglio eseguire il metodo carType.

Ogni aiuto è apprezzato

+4

http: // StackOverflow .com/questions/23445/how-best-to-compare-two-collections-in-java-and-act-on-them –

+0

Quale risultato ti aspetti dal confronto? vuoi estrarre gli elementi che non sono cambiati? hai bisogno di sapere il loro indice nelle collezioni (è lo stesso in entrambi) ... – pgras

+0

Ci scusiamo per la descrizione vaghe. Le raccolte saranno nello stesso ordine e nella stessa dimensione. Alcuni dei dati della nuova raccolta verranno aggiornati dalla raccolta precedente. Basati su carType, registrationNo e insurancePolicy sono gli stessi in entrambe le raccolte, quindi eseguirò un altro codice. – damien535

risposta

21

Difficile aiutare, perché non ci hai detto come ti piace confrontare le collezioni (di pari dimensioni). Alcune idee, sperando che uno si adatta:

Confronta entrambe le collezioni se contengono gli stessi oggetti nello stesso ordine

Iterator targetIt = target.iterator(); 
for (Object obj:source) 
    if (!obj.equals(targetIt.next())) 
    // compare result -> false 

Confronta entrambe le collezioni se contengono gli stessi oggetti in qualsiasi ordine

for (Object obj:source) 
    if (target.contains(obj)) 
    // compare result -> false 

Trova elementi in altra collezione che ha cambiato

Iterator targetIt = target.iterator(); 
for (Object obj:source) 
    if (!obj.equals(targetIt.next()) 
    // Element has changed 

Sulla base di un commento, questo algoritmo avrebbe fatto. Raccoglie tutte le auto che sono state aggiornate. Se il risultato del metodo è un elenco vuoto, entrambe le raccolte contengono voci uguali nello stesso ordine. L'algoritmo si basa su su un'implementazione corretta di equals() sul tipo Car!

public List<Car> findUpdatedCars(Collection<Car> oldCars, Collection<Car> newCars) 
    List<Car> updatedCars = new ArrayList<Car>(); 
    Iterator oldIt = oldCars.iterator(); 
    for (Car newCar:newCars) { 
    if (!newCar.equals(oldIt.next()) { 
     updatedCars.add(newCar); 
    } 
    } 
    return updatedCars; 
} 
+0

Stai usando 'new' nel tuo parametro che non è permesso. Inoltre, dov'è questo 'new' usato in' findUpdatedCars'? –

+0

@Shervin - grazie per l'osservazione! Risolti i problemi. –

+0

se non ti dispiace ho cambiato il valore di ritorno –

6
  • iterare la prima raccolta e inserirlo in un Map<Entity, Integer> cui Entity è la classe di essere memorizzati nella vostra collezione e la Integer rappresenta il numero di volte in cui si verifica.
  • Iterate sulla seconda raccolta e, per ogni elemento, tentare di cercarlo nel Map - Se esiste, quindi decrementare il valore Integer di uno ed eseguire qualsiasi azione necessaria quando viene trovata una corrispondenza. Se il valore Integer ha raggiunto lo zero, rimuovere la voce (Entità, Intero) dalla mappa.

Questo algoritmo verrà eseguito in tempo lineare presumendo di aver implementato un efficiente metodo hashCode().

1

Se non è preoccupato per i casi come (2,2,3), (2,3,3):

static <T> boolean equals(Collection<T> lhs, Collection<T> rhs) { 
    return lhs.size() == rhs.size() && lhs.containsAll(rhs) && rhs.containsAll(lhs); 
} 
8

Dalle aritmetica set, il set di A e B sono uguali se e solo se A sottotitoli B e B sottotitoli A.Così, in Java, dato due collezioni A e B è possibile controllarne l'uguaglianza senza rispetto all'ordine degli elementi con

boolean collectionsAreEqual = A.containsAll(B) && B.containsAll(A); 
+1

questa affermazione è vera per gli insiemi ma potrebbe non essere vera per gli elenchi o altre strutture che consentono voci duplicate (in altre parole, usa set quando possibile per semplificare la tua logica) – cfeduke

3

leggermente aggiornata una considerazione i valori nulli:

static <T> boolean equals(Collection<T> lhs, Collection<T> rhs) { 
    boolean equals = false; 
    if(lhs!=null && rhs!=null) { 
     equals = lhs.size() == rhs.size() && lhs.containsAll(rhs) && rhs.containsAll(lhs); 
    } else if (lhs==null && rhs==null) { 
     equals = true; 
    } 
return equals; 
}