Zurück in OO Grundlagen. Wie funktioniert LinkedHashMap unter der Haube? Kann das nicht herausfinden

8

Ich lese über LinkedHashMap und von der Beschreibung (obwohl sehr interessant) Ich konnte nicht verstehen, wie es unter der Haube funktioniert. Als eine Randnotiz weiß ich, wie ein HashMap darunter in Java funktioniert.
Also überprüfe ich die Quelle und kann immer noch nicht herausfinden, wie es funktioniert. Vielleicht fasse ich in OOP in diesem Falle nicht so etwas Grundlegendes mit mir Um den Teil zusammenzufassen, der für mich verwirrend ist, ist folgendes:
Die LinkedHashMap delegiert alle Aufrufe an ihre Eltern HashMap .
Intern überschreibt es die HashMap.Entry , um die verschiedenen Methoden recordAccess und recordRemoval zu implementieren, die die Logik der LinkedHashMap
zu implementieren scheinen Aber die tatsächlichen Entries sind innerhalb der Tabelle der Basisklasse, d. H. Der HashMap , die eine Tabelle von HashMap.Entry und nicht von LinkedHashMap.Entry instanziiert.
Ich kann also nicht herausfinden, wie die verschiedenen recordAccess und recordRemove usw. tatsächlich aufgerufen werden.
Kann mir jemand helfen zu verstehen, was hier vor sich geht?
Bin ich richtig zu denken, dass irgendwie LinkedHashedMap.Entry der Typ der Tabelle ist, die von HashMap erstellt wurde? Aber wie?

UPDATE:
Meine Frage ist, wie der recordAccess aufgerufen wird. Mein Experiment dazu mit einer abgeleiteten Version von HashMap ist aus dem Grund von Shengyuan Lu (+1) - Mein schlechtes dort

gescheitert

UPDATE:
Das Folgende, was ich ausprobiert habe, ist das gleiche (was ich denke), was der LinkedHashMap macht:

%Vor%

Aber es druckt:

%Vor%

Also wird das abgeleitete Entry niemals aufgerufen.
Ist mein Beispiel irgendwie anders? Ich kann nicht verstehen, wie das für LinkedHashMap

funktioniert     
Cratylus 03.06.2012, 12:29
quelle

2 Antworten

3

Wenn Sie MyLinkedHashMap im Paket java.util definieren, wird es kompiliert;)

Weil HashMap.HashEntry Paketsichtbarkeit ist.

PLUS:

Ich denke, das Wichtigste, was Sie verwirrt haben, ist LinkedHashMap.Entry vs HashMap.Entry . Der Punkt ist LinkedHashMap.Entry is-a HashMap.Entry. Tatsächlich speichert HashMap.table LinkedHashMap.Entry in LinkedHashMap.

In Bezug auf recordAccess und recordRemoval überschreiben beide die HashMap.Entry-Versionen. Sie können die Referenzen sowohl in LinkedHashMap als auch in HashMap finden.

Fügen Sie hier Kommentare hinzu: Ihr Beispielcode stimmt nicht mit LinkedHashMap implementation überein. Sehen Sie stattdessen LinkedHashMap.addEntry() .

    
卢声远 Shengyuan Lu 03.06.2012, 12:41
quelle
2

Strg + F ist hier Ihr Freund, besonders wenn Sie mehrere Dateien gleichzeitig durchsuchen können. recordAccess wird für den aufgerufenen / erstellten Eintrag von den Methoden put und get der Karte aufgerufen. (Die Aufrufe sind in HashMap.put , HashMap.putForNullKey und LinkedHashMap.get .) Dies ist nur relevant, wenn Sie den Konstruktor der LinkedHashMap verwenden, der einen booleschen Parameter akzeptiert und true an diesen übergeben hat. Dies hat zur Folge, dass beim Berühren der Karte der berührte Eintrag an die Vorderseite der internen verknüpften Liste verschoben wird.

Zitieren der Dokumentation:

  

Ein spezieller Konstruktor wird bereitgestellt, um eine verknüpfte Hash-Map zu erstellen, deren Iterationsreihenfolge die Reihenfolge ist, in der zuletzt auf die Einträge zugegriffen wurde, vom letzten bis zum letzten Zugriff (Zugriffsreihenfolge). Diese Art von Map eignet sich gut zum Erstellen von LRU-Caches. Das Aufrufen der put- oder get-Methode führt zu einem Zugriff auf den entsprechenden Eintrag (vorausgesetzt, es existiert nach Abschluss des Aufrufs). Die putAll-Methode generiert einen Eintragszugriff für jede Zuordnung in der angegebenen Zuordnung in der Reihenfolge, in der Schlüsselwertzuordnungen vom angegebenen Iterator für die Eintragsgruppe der angegebenen Zuordnung bereitgestellt werden. Keine anderen Methoden generieren Eingabezugriffe. Insbesondere wirken sich Operationen auf Collection-Views nicht auf die Reihenfolge der Iteration der Backing Map aus.

     

Die removeEldestEntry (Map.Entry) -Methode kann überschrieben werden, um eine Richtlinie zum automatischen Entfernen von veralteten Zuordnungen zu erzwingen, wenn neue Zuordnungen zur Map hinzugefügt werden.

Ähnlich wird recordRemoval von HashMap.removeEntryForKey und HashMap.removeMapping aufgerufen.

    
Wormbo 03.06.2012 13:08
quelle

Tags und Links