what - using hashmap java




Endlosschleife bei mehrfachem Verwenden eines Schlüssels in HashMap (4)

Problem ist nicht, dass die Hash-Map den Stapel für "denselben Schlüssel" zweimal durchbrennt, sondern wegen Ihrer speziellen Wahl des Kartenschlüssels. Sie fügen sich selbst eine Hash-Map hinzu.

Um das besser zu erklären - ein Teil des Map-Vertrags besteht darin, dass Schlüssel sich nicht in einer Weise ändern dürfen, die ihre Gleich (oder HashCode für diese Angelegenheit) -Methoden beeinflusst.

Wenn Sie map sich selbst als Schlüssel hinzugefügt haben, haben Sie den Schlüssel (map) so geändert, dass er einen anderen hashCode zurückgibt als beim ersten Hinzufügen von map.

Weitere Informationen hierzu finden Sie im JDK-Dock für die Map-Schnittstelle:

Hinweis: Vorsicht ist geboten, wenn veränderbare Objekte als Map-Schlüssel verwendet werden. Das Verhalten einer Map wird nicht angegeben, wenn der Wert eines Objekts in einer Weise geändert wird, die Gleichheitsvergleiche beeinflusst, während das Objekt ein Schlüssel in der Map ist. Ein Sonderfall dieses Verbots ist, dass eine Karte sich nicht als Schlüssel enthalten darf. Während es zulässig ist, dass eine Karte sich selbst als Wert enthält, ist äußerste Vorsicht geboten: Die Methoden equals und hashCode sind auf einer solchen Karte nicht mehr gut definiert.

HashMap fällt in eine Endlosschleife.

Ich bin nicht in der Lage zu verstehen, warum HashMap stackoverflow Fehler verursacht, wenn derselbe Schlüssel mehrmals verwendet wird.

Code:

import java.util.HashMap;

public class Test {
    public static void main(String[] args) {
        HashMap hm = new HashMap();

        hm.put(hm, "1");
        hm.put(hm, "2");
    }
} 

Error:

Ausnahme im Thread "main" java.lang.StackOverflowError


Sie verwenden als Schlüssel die Hashmap selbst -> das bedeutet Rekursion -> keine Ausgangsbedingung -> .

Verwenden Sie einfach einen Schlüssel (Long, String, Objekt, was auch immer Sie wollen).

Und ja, wie Seek Addo vorschlagen, fügen Sie Typen mit <> Klammern hinzu.


Es ist nicht möglich, eine Map selbst als Schlüssel hinzuzufügen. Aus javadoc :

Ein Sonderfall dieses Verbots ist, dass eine Karte sich nicht als Schlüssel enthalten darf .

Das Problem ist, dass Sie als Schlüssel kein Standardobjekt (irgendein Objekt mit gut definierten equals und hashCode Methoden, das ist nicht die Karte selbst) verwenden, sondern die Karte selbst.

Das Problem besteht darin, wie der hashCode der HashMap berechnet wird:

public int hashCode() {
   int h = 0;
   Iterator<Entry<K,V>> i = entrySet().iterator();
   while (i.hasNext())
       h += i.next().hashCode();
   return h;
}

Wie Sie sehen können, iteriert der Hash-Code der Karte über alle Elemente der Karte. Und für jedes Element berechnet es den HashCode. Da das einzige Element der Karte als Schlüssel die Karte selbst ist, wird sie zu einer Rekursionsquelle.

Ersetzen der Karte durch ein anderes Objekt, das als Schlüssel verwendet werden kann (mit gut definierten equals und hashCode ) funktioniert:

import java.util.HashMap;

 public class Test {
   public static void main(String[] args) {
     HashMap hm = new HashMap();

     String key = "k1";
     hm.put(key, "1");
     hm.put(key, "2");
   }
} 

Sie verwenden den gleichen Objektnamen wie einen Schlüssel, so dass es sich um eine Endlosschleife handelt.

also ist es Stacküberlauf.





stack-overflow