2016-03-29 7 views
1

Wenn zwei Objekte denselben Wert von ele in der Klasse A haben, dann sind diese beiden Objekte gleich. Also habe ich toString und hashCode überschrieben, um die ele des Objekts zurückzugeben (ohne den Wert von s irgendwo zu berücksichtigen).Java - Übergeordnete hashCode und toString

public class A { 
    private int ele; 
    private String s; 

    public int getEle() { 
     return ele; 
    } 

    public void setEle(int ele) { 
     this.ele = ele; 
    } 

    public String getS() { 
     return s; 
    } 

    public void setS(String s) { 
     this.s = s; 
    } 

    @Override 
    public int hashCode(){ 
     return ele; 
    } 

    @Override 
    public String toString() { 
     return String.valueOf(ele); 
    } 
} 

public static void main(String[] args) { 

    Map<A, String> map = new HashMap<>(); 
    A a1 = new A(); 
    a1.setEle(10); 
    a1.setS("abc"); 

    A a2 = new A(); 
    a2.setEle(10); 
    a2.setS("efg"); 

    map.put(a1, "val1"); 
    map.put(a2, "val2"); 

    System.out.println(map.get(a1)); 
    System.out.println(map.get(a2)); 

} 

Ausgang:

val1 
val2 

Aber wenn ich Wert lege von a1 und a2 in einer Karte, erwarte ich entweder val1 oder val2 wird für beide map.get(a1) zurück und map.get(a2).

Antwort

7

Sicher, a1 und a2 haben den gleichen Hash-Code, aber sie waren nicht als gleich betrachtet, weil Sie nicht equals außer Kraft gesetzt hat zwei A Objekte mit demselben ele zu betrachten gleich zu sein. Eine Karte wird equals zu dem endgültigen Lineal auf Gleichheit verwenden, nachdem es den Hash-Code verwendet. Die Karte platziert beide Objekte in demselben Bucket, aber weil sie nicht gleich sind, behält sie beide bei.

Aufschalten equals, so dass es wieder true wenn das andere Objekt ein A ist und sie beide haben die gleiche ele. Dann werden Sie sehen, dass val2 für beide Anrufe get zurückgegeben wird.

+0

Oh ya .. Mein schlechtes. Ich dachte, es verwendet toString, um die Zeichenfolgendarstellung zu erhalten und dann zu vergleichen – Ashwin

+0

Aber ich denke, es verwendet eine Liste beim Verketten. Aber ich gebe zuerst val1 ein. Aber ich bekomme val2 für beide. Warum? – Ashwin

+0

Wenn Sie 'a2' in die Karte' packen', wird sie von der Karte als 'a1' betrachtet, da' equals' 'true' zurückgibt. Die Map ersetzt dann das Schlüssel-Wert-Paar (ein 'Entry'), das da war,' a1 -> "val1" ', mit' a2' -> "val2". Beide 'Get'-Aufrufe führen zu 'equals', die' true' zurückgeben, sodass der aktuelle Wert '' val2'' jedes Mal abgerufen wird. – rgettman

0

Jedes Mal, wenn Sie new Schlüsselwort verwenden, macht es einen neuen object in heap Speicher. Also, a1 und a2 beide sind unterschiedliche Objekte in der Praxis.

Bitte beachten Sie diese für weitere Informationen über new Stichwort What New keyword do Internally in Java

1

Sie müssen equals implementieren() ele Wert zu berücksichtigen, wenn sie auf einer Karte hinzufügen, das heißt:

public class A { 

    private int ele; 
    private String s; 

    public int getEle() { 
     return ele; 
    } 

    public void setEle(int ele) { 
     this.ele = ele; 
    } 

    public String getS() { 
     return s; 
    } 

    public void setS(String s) { 
     this.s = s; 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 

     A a = (A) o; 

     return ele == a.ele; 

    } 

    @Override 
    public int hashCode() { 
     return ele; 
    } 
} 

Dadurch werden Sie machen gib nur einen Wert zurück, wie du willst.