2011-11-30 16 views
22

ho qualche oggettodi ArrayList Contiene metodo

class A { 
    private Long id; 
    private String name; 
    public boolean equals(Long v) { 
    return this.id.equals(v); 
    } 
} 

e ArrayList di questi oggetti. Quello che voglio è essere in grado di controllare se quell'elenco contiene qualche oggetto per campo dell'oggetto. Per esempio:

ArrayList<A> list = new ArrayList<A>(); if (list.contains(0L)) {...} 

ma overrided Equals metodo non mi aiuta. Cosa sto facendo di sbagliato? Grazie metodo

UPDATE E dovrei ignorare un codice hash() troppo?

+0

hai sovrascritto equals() nella classe A? se sì, puoi postarlo qui? – c05mic

+0

A giudicare dalle risposte seguenti, immagino che non ci sia una soluzione conveniente a questo. Penso che questo possa essere risolto con un'implementazione anonima della classe, come quella che si usa quando si chiama Collections.sort() con il proprio comparatore. – kodu

+0

Dopo aver cercato un po 'di più, ho trovato alcune risposte utili qui: http://stackoverflow.com/questions/587404/finding-all-objects-that-have-a-given-property-inside-a-collection – kodu

risposta

38

ecco qualche codice che potrebbe dimostrare come funziona:

import java.util.ArrayList; 

class A { 
    private Long id; 
    private String name; 

    A(Long id){ 
     this.id = id; 
    } 

    @Override 
    public boolean equals(Object v) { 
     boolean retVal = false; 

     if (v instanceof A){ 
      A ptr = (A) v; 
      retVal = ptr.id.longValue() == this.id; 
     } 

    return retVal; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 7; 
     hash = 17 * hash + (this.id != null ? this.id.hashCode() : 0); 
     return hash; 
    } 
} 

public class ArrayList_recap { 
    public static void main(String[] args) { 
     ArrayList<A> list = new ArrayList<A>(); 

     list.add(new A(0L)); 
     list.add(new A(1L)); 

     if (list.contains(new A(0L))) 
     { 
      System.out.println("Equal"); 
     } 
     else 
     { 
      System.out.println("Nah."); 
     }  
    } 

} 

In primo luogo, v'è un override dei Equals (Object o) metodo. Poi c'è anche l'override dell'hashCode(). Si noti inoltre che l'istanza di un controllo negli uguali garantirà che non si stia tentando di confrontare oggetti diversi.

Questo dovrebbe fare il trucco! Spero che abbia aiutato! Saluti :)

+0

bel esempio Grazie! –

+0

Funziona anche con contiene il metodo All? – Amriteya

+0

Funziona per contiene Tutto – Amriteya

8

Non hai sovrascritto il metodo nella tua classe. Per poter eseguire l'override, i parametri del metodo devono essere dello stesso tipo.

dovrebbe essere

public boolean equals(Object o) { 

} 

dove, come nel tuo caso è

public boolean equals(Long o) { 

} 

probabilmente bisogno di fare questo

public boolean equals(Object o) 
    { 
     if (o == null) return false; 
     if (o == this) return true; //if both pointing towards same object on heap 

      A a = (A) o; 
     return this.id.equals(a.id); 
    } 
+0

Ho aggiornato il codice, ma il risultato è lo stesso. Contiene non riesci a trovare un oggetto con ID specifico – nKognito

+0

puoi per favore pubblicare il codice pertinente. – Zohaib

+1

Vedere la mia risposta per una possibile spiegazione - * "L'altro problema ..." * –

7

Quello che sto facendo male?

Non si sta ignorando. Stai sovraccaricando.

Il metodo contains chiama il metodo equals con la firma equals(Object), quindi questo (nuovo) metodo che hai aggiunto non verrà chiamato.

L'altro problema è che il metodo equals ha la semantica errata per contains. Il metodo contains deve confrontare this con un oggetto che potrebbe essere un membro dell'elenco. L'elenco non contiene oggetti Long. Contiene oggetti di tipo A.

Ora si potrebbe ottenere questo ... se si utilizzano tipi di elenco non elaborati ... ma quello che si sta tentando di fare è una violazione del contratto API e delle cattive pratiche. Una soluzione migliore è quella di iterare e testare esplicitamente gli elementi dell'elenco.


E dovrei ignorare un codice hash() metodo di troppo?

Se si ignora equals(Object) allora si dovrebbe anche ignorare hashcode().

Qui non farà alcuna differenza, ma è essenziale se si mettono gli oggetti A in strutture di dati con hash. E poiché non sai cosa farà il prossimo con il tuo codice, è buona norma assicurarti che equals(Object) e hashCode() abbiano una semantica compatibile.

+0

Grazie per la spiegazione – nKognito