# HashMap.containsKey.



## buzl (14. Apr 2007)

Hallo,

ich habe eine HashMap wo eine Klasse als Schlüssel und ein Integer als Wert hergenommen wird, hier genannt map.

Die Schlüsselklasse enthält zwei IntegerInstanzvariablen die x und y Wert eines Koordinatensystems repräsentieren.

Wenn ich nun zwei Schlüsselwertepaare in meine HashMap eintrage. 
Sagen wir Klasse a mit x = 1 und y = 2 und 
Klasse b mit x = 2 und y = 3.

Die Klasse stellt nun eine Methode bereit mit der ich x und y verändern kann.
Vereinfacht erhöht sie hier x und y jeweils um 1 und nene siee inkrement.

Wenn ich jetzt mit mit map.containsKey(a.inkrement()) abfrage gibt er mit false zurück.

Meines Wissen frägt die Methode containsKey doch die Gleichheit des Schlüsselpaares bei Klassen mit equals ab.

ich habe in meiner Klasse equals überschrieben das es x und y vergleicht.

auch hashCode habe ich überschrieben und das inkrementierte a hat den selben hashCode wie das ursprüngliche a.

Wieso liefert mir containsKey dann false zurück?

Ich hoffe jemand hat eine Lösung für mein Problem. Danke im Voraus.


----------



## Wildcard (14. Apr 2007)

> ich habe in meiner Klasse equals überschrieben das es x und y vergleicht.
> 
> auch hashCode habe ich überschrieben und das inkrementierte a hat den selben hashCode wie das ursprüngliche a.
> 
> Wieso liefert mir containsKey dann false zurück?


Wenn du x und y inkrementierst sind sie offensichtlich nicht mehr gleich, folglich liefert deine equals 'false'


----------



## Leroy42 (14. Apr 2007)

Ganz einfach, WEIL du equals und hashCode überschrieben hast.

Dadurch wird dein Objekt unter einem Hashcode gespeichert,
der, nach Veränderung des Objekts, nicht mehr dem aktuellen
Hashcode entspricht.

Folglich kann das Objekt auch nicht wiedergefunden werden.


----------



## NTB (14. Apr 2007)

hmm aber er hat ja gesagt, dass das inkrementierte a den gleichen Hash hat, wie das ursprüngliche.
Hast Du Lust, eben ein Beispiel zu basteln?


----------



## Leroy42 (14. Apr 2007)

Das habe ich überlesen.

Dennoch: Eine Hashmap sucht zuerst über den Hashcode
(der dann ja korrekt ist) und danach über equals


----------



## NTB (14. Apr 2007)

Ich hab mir mal die Mühe gemacht:


```
public class Test {

    public static void main(String[] args) {
        MyObject mo = new MyObject();
        HashMap hm = new HashMap();
        hm.put(mo,new Integer("42"));
        System.out.println(hm.containsKey(mo));
        mo.increment();
        System.out.println(hm.containsKey(mo));
    }
}

class MyObject {
    private int x = 1;
    private int y = 1;
    
    public void increment()  {
        x++;
        y++;
    }
    
    public boolean equals() {
        return x==y;
    }
    
    public int hashCode() {
        return 5;
        //return x+y;     // das liefert ein false
    }
```

Ergibt beide Male true. 
Die Equals Methode wird allerdings gar nicht gebraucht. Ich denke mal, Du hast irgendwo anders noch einen Fehler. Sicher, dass der Hashcode auch nach dem Inkrementieren gleich ist?


----------



## buzl (14. Apr 2007)

Danke für die Antworten.

Hab jetzt mal vereinfacht die Klasse mit Testausgaben gepostet.


```
public class Node {
	
	private int x,y;

	public Node(int[] pos) {
		this(pos[0], pos[1]);
	}
	
	public Node(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
	public Node neighbours(BaseRobot.Direction direction) {
		switch(direction) {
			case NE:
				return new Node(x+1, y+1);
			case NW:
				return new Node(x-1, y+1);
			case SW:
				return new Node(x+1, y-1);
			case SE:
				return new Node(x-1, y-1);
			case W:
				return new Node(x+1, y);
		}
		// East als default
		return new Node(x-1, y);
	}
	
	public boolean equals(Node other) {
		return x == other.x && y == other.y;
	}
	
	public String toString() {
		return x+"/"+y;
	}
	
	public int hashCode() {
		return x+y;
	}
	
	public static void main(String... args) {
		int[] a = new int[] {1, 2};
		Node one = new Node(a);
		int[] b = new int[] {2, 3};
		Node two = new Node(b);
		System.out.println(one.equals(two.neighbours(BaseRobot.Direction.SE)));
		HashMap<Node, Integer> lala = new HashMap<Node, Integer>();
		lala.put(one, 1);
		lala.put(two, 2);
		System.out.println(lala.toString());
		Node three = one.neighbours(BaseRobot.Direction.E);
		System.out.println(three.toString());
		System.out.println(lala.containsKey(three));
		
		System.out.println("");
		int aa = 1;
		int bb = 2;
		HashMap<Integer, Integer> lulu = new HashMap<Integer, Integer>();
		lulu.put(aa, 1);
		lulu.put(bb, 2);
		System.out.println(lulu.containsKey(aa));
	}
```

Ausgabe:

true
{1/2=1, 2/3=2}
0/2
false

true


----------



## NTB (14. Apr 2007)

Mach doch mal  in der leeren Zeile dieser Main folgendes:


```
System.out.println(one.hashCode);
System.out.println(two.hashCode);
System.out.println(three.hashCode);
```

was kommt da raus?


----------



## buzl (14. Apr 2007)

haben den selben hashCode

ich muss jetzt weg drum werde ich länger nicht antworten können.

ich melde mich dannach wieder


----------



## NTB (14. Apr 2007)

Du willst doch erreichen, dass "contains(three)" ein "true" zurückgibt, weil es von "one" kommt, oder nicht?

Dazu müssen one und three den gleichen hashCode haben. Haben sie aber natürlich nicht.


----------



## buzl (15. Apr 2007)

wie gesagt sie haben den gleichen hashCode

hab in der main oben nen kleinen fehler gehabt nur vertippt aber schau mal:

neue main:

```
public static void main(String... args) {
		int[] a = new int[] {1, 2};
		Node one = new Node(a);
		int[] b = new int[] {2, 3};
		Node two = new Node(b);
		System.out.println(one.equals(two.neighbours(BaseRobot.Direction.SE)));
		HashMap<Node, Integer> lala = new HashMap<Node, Integer>();
		lala.put(one, 1);
		lala.put(two, 2);
		System.out.println(lala.toString());
		Node three = one.neighbours(BaseRobot.Direction.NE);
		System.out.println(three.toString());
		System.out.println(lala.containsKey(three));
		
		System.out.println(one.hashCode());
		System.out.println(two.hashCode());
		System.out.println(three.hashCode()); 
	}
```

Ausgabe:
true
{1/2=1, 2/3=2}
2/3
false
3
5
5

also three hat nach neighbours() x = 2 und y = 2
und two und three haben den selben hashCode...
und equals müsste ja dann auch true liefern weil ichs ja überladen hab, wie du oben sehen kannst.

darum versteh ich einfach nicht warum er false zurückgibt.

na vllt. weiß es ja jemand. danke im voraus.


----------

