Ich versuche, einen Satz von Arrays von Ints zu schaffen, das, was ist, wenn ich versuche zu tun:Hinzufügen von Arrays mit gleichen Werten ergeben doppelte Elemente Hashset
HashSet<int[]> s = new HashSet<int[]>();
int a1[] = {1,2,3};
int a2[] = {1,2,3};
s.add(a1);
s.add(a2)
System.out.println(s.size());
Dann s zwei Objekte hat, aber es sollte nur einen geben. Hinweis: Es spielt keine Rolle, ob HashSet < Integer []> ist. Es funktioniert einfach nicht.
Jetzt Wenn ich versuche, dies mit einer Arraylist < Integer zu tun>, so etwas wie:
HashSet<ArrayList<Integer>> s = new HashSet<ArrayList<Integer>>();
ArrayList<Integer> a1 = new ArrayList<Integer>();
ArrayList<Integer> a2 = new ArrayList<Integer>();
a1.add(1);
a1.add(2);
a1.add(3);
a2.add(1);
a2.add(2);
a2.add(3);
s.add(a1);
s.add(a2)
System.out.println(s.size());
Dann hat s ein Objekt.
I obwohl ein Weg, um den Fehler in dem ersten Code zu vermeiden, und wurde in einem Hashset Hashcodes jeden Arrays wie folgt zu speichern:
int a1[] = {0,10083,10084,1,0,1,10083,0,0,0,0};
int a2[] = {1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0,2112};
HashSet<Integer> s= new HashSet<Integer>();//hashcodes of each array
s.add(Arrays.hashCode(a1));
s.add(Arrays.hashCode(a2));
System.out.println(Arrays.hashCode(a1));
System.out.println(Arrays.hashCode(a2));
System.out.println(s.size());
Es arbeitet für den ersten Fall (1,2,3), aber in Fällen, in denen Kollisionen nicht funktionieren, müsste ich Kollisionen verwalten. Also denke ich, dass ich ein HashSet selbst implementiere.
Mit HashSet < ArrayList < Integer >> es funktioniert perfekt. Ich nehme an, dass Java Kollisionen in diesem Fall verwaltet.
Meine Frage ist, warum Java erlaubt keine HashSet < int [] zu verwalten> oder HashSet < Integer []> wenn Hashcodes erzeugt sind die gleichen wie in Arraylist < Integer> und Hashcodes von Arrays können einfach durch den Aufruf berechnet werden Arrays.hashCode (...).
Und schließlich, wenn ich ein HashSet < int []> (oder HashSet < Integer []>) machen möchte, müsste ich es selbst implementieren? Oder gibt es einen besseren Weg?
Danke.
UPDATE: Ok, endlich denke ich, ich bin zu einer vollständigen Antwort gekommen. Wie @ZiyaoWei und @ user1676075 kommentiert, funktioniert es nicht, weil equals false zurückgibt und hashcodes differents sind. Aber, warum Java diese Methoden nicht überschreibt (mit Arrays.equals(), Arrays.hashCode()), also kann man etwas wie HashSet tun < int []>? Die Antwort ist, weil ein Array ein veränderbares Objekt ist und Hashcode nicht von veränderbaren Werten abhängig sein kann (jedes Element des Arrays ist ein veränderbarer Wert), gemäß dem allgemeinen Vertrag des Hashcodes. Mutable objects and hashCode
Hier schöne Erklärungen der Verwendung wandelbar Felder in hashCode http://blog.mgm-tp.com/2012/03/hashset-java-puzzler/ und wandelbar Schlüssel in Hashmaps Are mutable hashmap keys a dangerous practice?
Meine Antwort ist, wenn Sie ein HashSet < int [] verwenden möchten> Sie eine Klasse erstellen müssen, dass eine hat Wenn Sie möchten, dass Hashcode und equals von Werten abhängen, überschreiben Sie die Methoden equals() und hashCode() mit Arrays.equals() und Arrays.hashCode(). Wenn Sie nicht gegen den Vertrag verstoßen wollen, machen Sie das Array endgültig.
Danke allen!
Siehe Ziyao Antwort unten. Überprüfen Sie kurz, ob a.hashCode() mit b.hashCode() übereinstimmt. Ich wette, sie sind nicht gleich. –
möglich duplicate von [wie man eine Reihe von Array in Java machen?] (Http://stackoverflow.com/questions/9841934/how-to-make-a-set-of-array-in-java) – Raedwald