2012-11-22 9 views
7

Mi stavo facendo un po 'di problemi con hashCode + equals + Map stuff e ho trovato qualcosa ... strano.'equals()' restituisce false, eppure l'oggetto si trova nella mappa

Il frammento è il seguente:

class Obj { 
    String n; 
    Obj(String n) {this.n = n;} 

    public int hashCode() {return 0;} 
    public boolean equals(Object o) {return false;} // no instance of this class 
                // equals any other instance 

} 

poi ho fatto qualcosa di simile:

java.util.Map<Obj,String> map = new java.util.HashMap<Obj,String>(); 
    Obj o1 = new Obj("1"); 
    Obj o11 = new Obj("1"); 
    Obj o2 = new Obj("2"); 

    map.put(o1,"val 1"); 
    map.put(o11,"val 2"); 
    map.put(o2,"val 3"); 

    p("size = " + map.size()); // obviously 3 
    p(map.get(new Obj("1"))); // obviously null  
    p(map.get(o1)); // ... 

L'ultima riga è la parte strana. L'ultima riga restituisce val 1. Come mai? Il metodo equals restituisce sempre false. È perché l'operatore == viene utilizzato prima che venga chiamato equals?

Grazie per qualsiasi intuizione.

risposta

7

In HashMap.java, il metodo è get:

public V get(Object key) { 
    if (key == null) 
     return getForNullKey(); 
    int hash = hash(key.hashCode()); 
    for (Entry<K,V> e = table[indexFor(hash, table.length)]; 
     e != null; 
     e = e.next) { 
     Object k; 
     if (e.hash == hash && ((k = e.key) == key || key.equals(k))) 
      return e.value; 
    } 
    return null; 
} 

La linea if (e.hash == hash && ((k = e.key) == key || key.equals(k))) effettivamente confronta le chiavi utilizzando == prima di chiamare equals. Ecco perché il tuo tentativo di eliminare l'uguaglianza fallisce.

Problemi correlati