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:
importjava.util.HashSet;importjava.util.Iterator;publicclassHashSetTest{publicstaticvoidmain(String[] args){HashSet<Kante> hs =newHashSet<Kante>();Kante e1 =newKante(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, 2System.out.println(e2 == e1);// Output: trueSystem.out.println(hs.contains(e2));// Komisch!!!! Hier finde diese hs die e2 nicht!!!}}
Hier ist die Kante Klasse:
Java:
publicclassKante{privateint x =0;privateint y =0;publicKante(int x,int y){this.x = x;this.y = y;}publicintgetX(){return x;}publicintgetY(){return y;}publicvoidsetX(int x){this.x = x;}publicvoidsetY(int y){this.y = y;}@Overridepublicbooleanequals(Object obj){if(this== obj)returntrue;if(obj ==null)returnfalse;if(getClass()!= obj.getClass())returnfalse;Kante other =(Kante) obj;if(x != other.x)returnfalse;if(y != other.y)returnfalse;returntrue;}@OverridepublicinthashCode(){finalint prime =31;int result =1;
result = prime * result + x;
result = prime * result + y;return result;}}
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.