suche Elemente in HashSet

fatfox

Bekanntes Mitglied
Hallo alle,

ich habe einen kleinen Test über HashSet gemacht, HashSet verhalten sich irgendwie sehr komisch. Könnt ihr mal erklären, warum ist das so?

ich füge ein Element "e1" in HashSet, danach verändere ich das Element "e1", dann findet HashSet das Element nicht mehr. Warum ist das so???

Hier ist der Konkrete Test:

Java:
import java.util.HashSet;
import java.util.Iterator;

public class HashSetTest {

	public static void main(String[] args) {

		HashSet<Kante> hs = new HashSet<Kante>();
		Kante e1 = new Kante(1, 2);
		hs.add(e1); // Füge e1 in hs ein

		e1.setX(5); // Veränder e1, jetzt ist e1: (5, 2)
		System.out.println(hs.contains(e1)); // Output: falsh!

		// Hole ich das Element von hs aus, schau mal, was drin ist:
		Iterator<Kante> it = hs.iterator();
		Kante e2 = it.next();
		System.out.println(e2.getX() + "," + e2.getY());// Output 5, 2

		System.out.println(e2 == e1); // Output: true

		System.out.println(hs.contains(e2)); // Komisch!!!! Hier finde diese hs die e2 nicht!!!

	}

}

Hier ist die Kante Klasse:

Java:
public class Kante {

	private int x = 0;
	private int y = 0;

	public Kante(int x, int y) {
		this.x = x;
		this.y = y;
	}

	public int getX() {
		return x;
	}

	public int getY() {
		return y;
	}

	public void setX(int x) {
		this.x = x;
	}

	public void setY(int y) {
		this.y = y;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Kante other = (Kante) obj;
		if (x != other.x)
			return false;
		if (y != other.y)
			return false;
		return true;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + x;
		result = prime * result + y;
		return result;
	}

}
 
Zuletzt bearbeitet:
Hi,
ersetze mal
Java:
System.out.println(e2 == e1); // Output: true

durch
Java:
System.out.println(e2.equals(e1)); // Output: true

kommt da noch true raus?

Gruß
 
Hi,
ersetze mal
Java:
System.out.println(e2 == e1); // Output: true

durch
Java:
System.out.println(e2.equals(e1)); // Output: true

kommt da noch true raus?

Gruß

Hi Firephoenix,

ja, selbst wenn e2.equals(e1), kommt auch "true" aus.

(Du kannst die 2 Dateien kopieren, und direkt laufen lassen.)
 
Zuletzt bearbeitet:
Bin grad den Code von HashSet duchgegangen soweit nötig. Also HashSet legt grob gesagt für jeden HashCode intern eine HashMap (Bucket) an. D.h. Die Kante landet in einem Bucket dass dem HashCode der anfänglichen Kantenwerte entspricht. Nach dem ändern der Kante mit e1.setX(5); hat die Kante einen neuen HashCode, wenn man dann mit hs.contains(e1) nachsieht, sucht das HashSet als erstes nach dem Bucket, findet aber für den neuen HashCode keinen. Mehr habe ich mir nicht angesehen. Beheben lässt sich das indem man eventuell eine Id für jede Kante verwendet, EDIT: hashCode nicht überschreibt oder Kante immutable macht.
 
Zuletzt bearbeitet:
Hi Raum114 und Marco,

tja, ich bin nicht der este, der Problem getroffen habe. 🙂

Also, ich akzeptiere, dass man nach dem Element hinzufügen den Element nicht verändern darf...

Das ist nicht nur bei HashSet, bei HashMap ist auch genau so....
 

Neue Themen


Zurück
Oben