2011-02-15 18 views
8

Dato due elenchi, ogni elenco con lo stesso tipo di oggetto, vorrei trovare gli oggetti tra i due elenchi che corrispondono, in base ad alcuni valori di proprietà.java - Come trovare gli oggetti corrispondenti tra due elenchi?

ad es. un oggetto da List1, L1Obj, corrisponde a un oggetto da List2, L2Obj, se L1Obj.a == L2Obj.a AND L1Obj.b == L2Obj.c AND L1Obj.c == L2Obj.c

Queste proprietà non sono le uniche proprietà della classe, ma sono tutto ciò che è necessario per identificare univocamente un oggetto all'interno di una lista.

La mia domanda è: qual è il modo migliore per raggiungere questo obiettivo?

Un modo sarebbe di costruire in HashMaps in base agli elenchi, con il valore di stringa concatenato di un + b + c utilizzato come chiave per indicizzare un oggetto. In questo modo ho potuto scorrere il primo elenco e tentare di cercare un oggetto nel secondo elenco con la stessa chiave.

Come suona? C'è un modo migliore per raggiungere questo?

Tutto l'aiuto è molto apprezzato!


UPDATE:

Okay, in realtà ho bisogno di un po 'di più. Dopo aver trovato una corrispondenza, desidero sovrascrivere le proprietà L1Obj.x, L1Obj.y, L1Obj.z con quelle di L2Obj. HashSet è ottimo per trovare le corrispondenze, ma se ho ragione non mi consente di accedere a queste partite.

Cosa posso fare a riguardo?

+0

è possibile modificare il codice delle classi memorizzate negli elenchi? – Alb

+0

@Alb sì Posso modificare il codice – QuakerOat

risposta

8

Gli oggetti che si desidera esaminare implementano equals(Object) e hashCode() che prendono in considerazione solo i campi che ti interessano? In tal caso, è possibile creare un nuovo HashSet dal primo elenco, quindi chiamare retainAll() passando al secondo elenco.

Se non implementano equals(Object) e hashCode() rispetto alle proprietà che ti interessano, è possibile creare un TreeSet e passare un Comparator che guarda le proprietà che ti interessano.

+0

Uso piacevole e appropriato di 'retainAll' –

0

Non so se mi pensando di facile, ma vorrei provare in quel modo:

l'override del metodo equals dell'oggetto per implementare il confronto per verificare se è lo stesso oggetto

Poi Vorrei scorrere il primo elenco e controllare con il metodo contiene se l'oggetto è contenuto anche nel secondo elenco.

Quindi vorrei scorrere il secondo elenco e controllare se l'oggetto si trova anche nel primo elenco e non già nell'elenco dei risultati.

3

Invece di usare il repesntation stringa, utilizzare il metodo equals() un HashSet come in:

class MyObj { 

    Property a; 
    Property b; 
    Property c; 

    public boolean equals(Object o) { 
     // use == if Property is primitive, like int or something 
     return o instanceof MyObj && a.equals(o.a) && b.equals(o.b) && c.equals(o.c); 
    } 

    // edit - when you override equals, also override hashcode 
    public int hashCode() { 
     return a.hashCode()^b.hashCode()^c.hashCode(); 
    } 

    public String toString() { 
     return a.toString() + " " + b.toString() + " " + c.toString(); 
    } 

} 

// later in your main method 
Set<MyObj> objSet = new HashSet<MyObj>(); 
for(MyObj o : list1) objSet.add(o); 
for(MyObj o : list2) if(objSet.contains(o)) System.out.println(o + " is a match!"); 
+0

È necessario modificare 'equals (MyObj o)' su 'equals (Object o)'. Non si esegue l'override degli uguali come scritto. – ILMTitan

+0

@Titan - Ho notato che l'hashCode mancava prima del tuo commento :). Avevo pensato che tu potessi lasciarlo come MyObj, ma lo pulirò per corrispondere agli standard. – corsiKa

0

L'oggetto in questione deve implementare il metodo boolean equals(Object). Es .:

L1Obj.equals(L2Obj); 

È possibile sovraccaricare tale metodo in modo da poter implementare le operazioni di uguaglianza desiderate.

1

Si può fare una cosa. Avere due liste con questi oggetti e sovrascrivere il metodo equals della classe a cui appartengono questi oggetti. vostro metodo equals dovrebbe essere simile

@Override 
public boolean equals(Object obj) 
{ 
    return (this.a == obj.a && this.b == obj.b && this.c == obj.c) 

} 

Ricordiamo anche, una volta che l'override metodo equals, è necessario eseguire l'override il metodo int hashCode() pure.

Una cosa da notare è che durante l'implementazione di hashCode() è che 2 oggetti uguali avranno lo stesso hashCode, mentre il contrario non è vero.

Problemi correlati