JDK1.8.0_144 Download Adresse: //www.vevb.com/softs/551512.html
AbstractMap Abstract Class implementiert einige einfache und allgemeine Methoden, die an sich nicht schwierig sind. In dieser abstrakten Klasse gibt es jedoch zwei Methoden, die es wert sind, darauf zu achten. Die Implementierung des Quellcodes der Schlüsselet- und Wertemethoden kann als Modelle im Lehrbuchstil bezeichnet werden.
Abstrakte Klassen werden normalerweise als Skelett implementiert, um gemeinsame Methoden für ihre jeweiligen Unterklassen zu implementieren. Im vorherigen Artikel haben wir die Kartenschnittstelle erläutert, und dieser Artikel analysiert und untersucht die AbstractMap -Abstract -Klasse.
In Java gibt es ziemlich viele Datenstrukturen vom Kartentyp. AbstractMap implementiert als Implementierung von Skelett einige Methoden der Kartenschnittstelle, dh es liefert öffentliche Methoden für ihre Unterklassen, und verschiedene Karte ohne Implementierung können unterschiedlich sein.
Eine abstrakte Klasse kann keine direkten Instanzen abstrakter Klassen über das neue Schlüsselwort erstellen, aber es kann Konstruktoren haben. AbstractMap liefert einen geschützten modifizierten parameterlosen Konstruktor, was bedeutet, dass nur seine Unterklasse zugreifen kann (natürlich ist es eine abstrakte Klasse selbst, und andere Klassen können nicht direkt instanziiert werden), dh nur seine Unterklasse kann diesen parameterlosen Konstruktor aufrufen.
Eine Eintragsschnittstelle wird intern in der Kartenschnittstelle definiert. Diese Schnittstelle ist eine interne Implementierung der Kartenkarte, um ein Schlüsselwertpaar zu verwalten, und der Schlüsselwert wird in dieser Karte gespeichert. AbstractMap implementiert diese interne Schnittstelle, insgesamt gibt es zwei: Einer ist das mutable SimpleEnry und der andere ist das unveränderliche SimplemibleableStry.
öffentliche statische Klasse SimpleEnry <K, V> implementiert Eintrag <k, v>, java.io.serializable
Die MAP.Entry <K, V> Schnittstelle ist implementiert und serialisierbar (kann serialisiert werden).
Seine Methode ist relativ einfach, alle sind Operationen des Eingehens von Werten und Speichern von Werten. Die Definition des Schlüsselwerts ist eine endgültige Modifikation, was bedeutet, dass es sich um eine unveränderliche Referenz handelt. Darüber hinaus ist seine SetValue -Methode etwas speziell. Der gespeicherte Wert ist nicht der gespeicherte Wert, sondern der alte Wert zurückgegeben. Was Sie lernen müssen, sind die gleichen und Hashcode -Methoden, die es neu schreiben.
public boolean Equals (Objekt o) {if (! (o Instanceof map.Entry)) //, um festzustellen, ob die Parameter von MAP.Enty -Typ sind. Map.Entry <?,?> E = (Map.Entry <?,?>) O; // Der Parameter verwendet den Objekttyp auf map.Entry -Typ "?" anstelle von "k, v", weil der Typ des Generika zur Laufzeit gelöscht wird. Der Compiler weiß nicht, in welchem Typ K und V, EQ (Schlüssel, e.getkey ()) && EQ (value, e.getValue ()); // Key und Value Rufen Sie die EQ -Methode für das Urteilsvermögen auf, und gleich sind gleich, wenn beide zurückkehren. } private statische boolesche EQ (Objekt O1, Objekt O2) {return O1 == NULL? O2 == NULL: O1.Equals (O2); // Dieser Drei-Punkte-Operator ist ebenfalls sehr einfach, aber es sollte beachtet werden, dass O1 und O2 hier Objekttypen sind, die Equals-Methode des Objekttyps jedoch durch "==" verwiesen wird. Denken Sie also nicht, dass es hier ein Problem gibt, da in der Realität der O1-Typ möglicherweise eine String-String sein kann, obwohl die String#Equals-Methode, wenn sie die Equals-Methode nennt. }Um die Equals -Methode korrekt neu zu schreiben und korrekt verwendet zu werden, müssen Sie normalerweise die HashCode -Methode neu schreiben.
public int HashCode () {return (key == null? 0: key.hashcode ()) ^ (value == null? 0: value.hashCode ()); // Wenn die Werte von Schlüssel und Wert nicht null sind, wird der HashCode Xored. }öffentliche statische Klasse SimplemimmableStry <K, V> implementiert Entrements <K, v>, java.io.Serializable SimplemimmableStropyEntry
Der Eintrag, der als unveränderlich definiert ist, ist tatsächlich unveränderlich, da er nicht die SetValue -Methode bereitstellt und natürlich nicht über die SetValue -Methode modifiziert werden kann, wenn mehrere Threads gleichzeitig zugegriffen werden. Im Vergleich zu SimpleEnry werden seine Schlüssel- und Wertelementvariablen als endgültige Typen definiert. Wenn Sie die SetValue -Methode aufrufen, wird eine nicht unterstützte Ausnahme von OperationException ausgelöst.
Seine Gleich- und Hashcode -Methoden stimmen mit SimpleEnry überein.
Überprüfen Sie als nächstes, welche Methoden in der Kartenschnittstelle von AbstractMap Abstract Class implementiert werden.
öffentliche int size ()
In der Karte ist eine Einstiegsmethode definiert, die die festgelegte Sammlung von MAP.Entry zurückgibt. Die Größenmethode der Set -Sammlung wird direkt aufgerufen, die die Größe der Karte hat.
öffentlich boolean isempty ()
Rufen Sie die obige Größenmethode auf, die 0 entspricht, sie ist leer.
Der öffentliche Boolesche enthält Keey (Objektschlüssel)
Die Implementierung dieser Methode ist relativ einfach. Durch Aufrufen der Einstiegsmethode wird Iterator der SET -Sammlung erhalten und mit dem Parameterschlüssel überquert. Die Karte kann als Schlüsselwert von Null gespeichert werden. Da Key = Null in MAP mit speziellen Spezialspeicher gespeichert ist (der HashCode -Wert kann nicht berechnet werden), haben wir auch eine Möglichkeit gemacht, zu bestimmen, ob der Parameterschlüssel leer ist.
Der öffentliche Boolesche enthält den Wert (Objektwert)
Diese Methodeimplementierung steht in Übereinstimmung mit den Enthaltungen.
öffentlich V GET (Objektschlüssel)
Diese Methode -Implementierung ähnelt den oben genannten zwei, der Unterschied besteht darin, dass das obige gleich dem Booleschen ist und diese Methode den Wert zurückgibt.
öffentlich V Put (K Key, V -Wert)
Die Methode zum Speichern von Schlüsselwertpaaren in die Karte wird nicht im Detail implementiert, und eine nicht unterstützte Operationxzeption wird direkt geworfen.
öffentlich V entfernen (Objektschlüssel)
Löschen Sie das in der Karte angegebene Schlüsselwertpaar über die Parameterschlüssel. Diese Methode ist auch sehr einfach. Es durchquert auch die festgelegte Sammlung von MAP.Entry durch einen Iterator, findet den entsprechenden Schlüsselwert und löscht MAP.Entry, indem Sie die Methode Iterator#entfernen.
public void putall (Karte <? Erweitert K,? Erweitert V> m)
Diese Methode ist auch sehr einfach, um die eingehende Karte zu durchqueren und einfach die Put -Methode aufzurufen, um sie zu speichern.
öffentliche void clear ()
Rufen Sie die Einstiegsmethode auf, um die SET -Sammlung abzurufen, und rufen Sie dann die Methode Set#Clear () auf, um sie zu löschen.
public set <k> keyset ()
Gibt die festgelegte Sammlung von Kartenschlüsselwerten zurück. AbstractMap definiert eine Mitgliedsvariable "Transient Set <K> Keyset". In JDK7 wird die Keyset -Variable durch volatile geändert, in JDK8 jedoch nicht durch flüchtiges modifiziert. In den Kommentaren zu der Schlüsselset -Variablen wird die Methode zum Zugriff auf diese Felder nicht für sich selbst synchronisiert, und flüchtig kann die Sicherheit der Gewinne nicht garantieren. Die Implementierung der Keyset -Methode ist interessant.
Denken Sie zunächst nach, dass diese Methode den Satz von Schlüsselwerten zurückgibt. Natürlich können wir uns eine einfache Implementierungsmethode vorstellen, das Eintragsarray durchqueren und den Schlüsselwert herausnehmen und in den SET -SET einfügen, ähnlich dem folgenden Code:
public set <k> keyset () {set <k> ks = null; für (map.entry <k, v> Eintrag: Einstieg ()) {ks.add (Eintrag.getKey ()); } return ks;}Dies bedeutet, dass jedes Mal, wenn die Keyset -Methode aufgerufen wird, das Eingangsarray durchquert und die Effizienz stark reduziert wird, wenn das Datenvolumen groß ist. Ich muss sagen, dass der JDK -Quellcode sehr gut geschrieben ist und nicht die Methode des Traverses übernimmt. Wenn Sie keinen Eintrag durchqueren, woher wissen Sie, dass die Karte zu diesem Zeitpunkt ein Schlüsselwertpaar für Schlüsselwert hinzugefügt hat?
Die Antwort besteht darin, eine neue benutzerdefinierte Set-Sammlung innerhalb der Keyset-Methode erneut zu implementieren, und die Iteratormethode wird in dieser benutzerdefinierten Set-Sammlung neu geschrieben. Hier ist der Schlüssel. Die Iteratormethode gibt die Iterator-Schnittstelle zurück und wird hier neu implementiert. Durch Aufrufen der Einstiegsmethode und dann die Iteratormethode. Das Folgende wird in Kombination mit dem Code analysiert:
public set <k> keyset () {set <k> ks = keyset; // Defined Transient Set <K> Schlüsselet if (ks == null) {// Der erste Aufruf ist definitiv NULL, erstellen Sie ein Set -Beispiel über den folgenden Code ks = new AbstractSet <k> () {// Erstellen Sie einen an seine kundenspezifischen Set öffentlichen Iterator <k> iterator () {// Die ITerator -Methode der IT -Kollektion neuer IT -Kollektion Neue ITROGRETER NEW NEW NEW RETURATUR <K> (). Iterator <Eintrag <k, v >> i = Eintragset (). Iterator (); // Erstellen Sie einen Iterator -Iterator der Set Collection public boolean hasNext () {return i.hasnext (); // Das Urteil des Schlüsselwerts ist das Urteil des Eintritts} public k next () {return i.Next (). GetKey (); // Der nächste Schlüsselwert besteht darin, den Eintrag#GetKey} public void remove () {i.remove (); // Löschen Sie den Schlüsselwert, löschen Sie die Eingabe}}; } public int size () {// Die umgeschriebene Set#Größenmethode gibt AbstractMap.this.size () zurück; // Der Wert des Schlüssels ist, wie groß die gesamte Karte ist. Rufen Sie also einfach die Größenmethode dieser Klasse auf. Dies ist eine interne Klasse. Verwenden Sie dieses Schlüsselwort, um diese Klasse direkt darzustellen. Es sollte angeben, dass die Größenmethode in AbstractMap aufgerufen wird. Ohne dies bedeutet dies, dass es sich um eine statische statische Methode handelt. // Um einen Schlüsselwert zu erhalten, bedeutet dies, ob die Karte leer ist. Daher ist es nur die Isempty -Methode dieser Klasse} public void clear () {// Die umgeschriebene Set#Clear -Methode AbstractMap.this.clear (); // Löschen Sie den Schlüsselwert, es dient nur, die Karte zu löschen. Es wird also nur die klare Methode dieser Klasse aufgerufen} Public Boolean enthält (Objekt k) {// set set#enthält Methode return contractmap.this.Containskey (k); // beurteilen, ob Set Daten k enthält, was bedeutet, ob die Karte den Schlüsselwert enthält. Rufen Sie also einfach die entsprechende Methode dieser Klasse auf}}. keyset = ks; // Weisen Sie diese benutzerdefinierte Set -Sammlung dem Variablenschlüsselset zu. Wenn Sie in Zukunft die Keyset -Methode erneut aufrufen, weil der Schlüsselset nicht null ist, müssen Sie nur direkt zurückkehren. } return ks;Ich denke, das ist eine sehr clevere Implementierung. Obwohl sich diese Methode um den Schlüsselwert dreht, kann sie tatsächlich in Kombination mit dem Eintritt implementiert werden, ohne den Eintrag zu durchqueren. Gleichzeitig wird oben erwähnt, dass das Aufrufen der Einstiegs -Iterator -Methode, bei der es sich um die beste Praxis des Vorlagenmethodenmodus handelt. Da das Einstiegssatz nicht in AbstractMap implementiert ist, sondern der Unterklasse überlassen wird, kann die Schlüsseletmethode jedoch mit einem "Algorithmus -Skelett" implementiert werden, das das Template -Methodenmuster ist.
öffentliche Sammlung <V> Werte ()
Für die Wertemethode können Sie den Schlüsselet vollständig beziehen. Die beiden haben den gleichen Effekt, daher werde ich es hier nicht wiederholen, um Platz zu sparen.
Public Abstract Set <Eintrag <K, v >> Einstiegset ()
Eine abstrakte Methode wird an seine Unterklasse übergeben, um zu vervollständigen, was darauf hinweist, dass diese Methode nicht besonders "allgemein" ist.
öffentlicher Boolesche gleich (Objekt O)
Die Karte sieht vor, dass der Schlüssel und der Wert jedes Schlüsselwertpaares in der Karte nur dann nacheinander entsprechen, die true zurückgegeben werden. Beurteilen Sie in der Methode zunächst die einfachen Bedingungen. Wenn die Referenzen gleich sind, kehren Sie direkt zurück. Wenn der Parameter O nicht der Kartentyp ist, geben Sie Falsch direkt zurück. Wenn die Anzahl der beiden Karte unterschiedlich ist, geben Sie Falsch direkt zurück. Erst dann über das Eintragsarray iterieren und vergleichen, ob der Schlüssel und der Wert in der Eingabe voneinander entsprechen. Die Methode ist einfach, aber dies gibt uns Inspiration. In dem bedingten Urteil sollten wir zuerst die einfachen Grundlagen beurteilen und dann die komplexen beurteilen.
public int hashcode ()
Schreiben Sie die Equals -Methode der Objektklasse neu, und es ist ebenfalls erforderlich, dass Hashcode umschreiben. Die Implementierung von HashCode durch AbstractMap besteht darin, die HashCode -Werte aller MAP hinzuzufügen. ENTELY (hier ist SimpleEnry oder SimpleMibleableStry) und die endgültige Summe wird als HashCode -Wert der MAP verwendet.
öffentlicher String -ToString ()
Es gibt nichts zu sagen über diese Methode, es soll alle Schlüsselwertpaare herausnehmen und StringBuilder verwenden, um sie zu spleißen.
geschützter Objekt Clone () wirft ClonenotsuptedEdException aus
Implementieren Sie eine flache Kopie, da es sich um eine flache Kopie des variablen Schlüsselsets und der Werte handelt, wodurch die durch die beiden flachen Kopien verursachten Probleme verhindert werden.