2012-11-22 6 views
7

Ich habe mit etwas hashCode + equals + Map-Kram herumgespielt und etwas ... seltsames gefunden.'equals()' gibt false zurück, aber das Objekt wurde in der Karte gefunden

Das Snippet ist wie folgt:

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 

} 

Dann habe ich so etwas wie diese:

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

Die letzte Zeile ist der seltsame Teil. Die letzte Zeile gibt val 1 zurück. Woher? Die Methode equals gibt immer false zurück. Ist dies, weil der == Operator verwendet wird, bevor equals aufgerufen wird?

Danke für jede Einsicht.

Antwort

7

In HashMap.java, die get Methode ist:

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

Die Linie if (e.hash == hash && ((k = e.key) == key || key.equals(k))) in der Tat der Schlüssel vor equals Aufruf mit == nicht zu vergleichen. Deshalb scheitert Ihr Versuch, die Gleichheit zu beseitigen.

Verwandte Themen