Eine Sammlung stellt eine Gruppe von Objekten dar , die Elemente der Sammlung.
Alle Klassen, die die Collection-Schnittstelle implementieren, müssen zwei Standardkonstruktoren bereitstellen: einen parameterlosen Konstruktor zum Erstellen einer leeren Collection und einen Collection-Parameterkonstruktor zum Erstellen einer neuen Collection, die dieselben Elemente enthält wie die übergebene Sammlung. Der letztere Konstruktor ermöglicht dem Benutzer das Kopieren einer Sammlung.
Wie durchläuft man jedes Element in der Sammlung? Unabhängig vom tatsächlichen Typ der Sammlung unterstützt es eine Iterator()-Methode, die einen Iterator zurückgibt. Sie können diesen Iterator verwenden, um jedes Element in der Sammlung zu durchlaufen. Das Durchlaufen der Sequenz ist nicht erforderlich .
Typische Verwendung ist wie folgt:
1 Iterator it = collection.iterator(); // 获得一个迭代子2 while(it.hasNext()) {3 Object obj = it.next(); // 得到下一个元素4 }
Liste ist eine geordnete SammlungVerwenden Sie diese Schnittstelle, um die Einfügeposition jedes Elements genau zu steuern. Benutzer können über den Index (die Position des Elements in der Liste, ähnlich einem Array-Index), der einem Java-Array ähnelt, auf Elemente in der Liste zugreifen.
Zusätzlich zur für die Collection-Schnittstelle erforderlichen Iterator()-Methode bietet List auch eine ListIterator()-Methode, die im Vergleich zur Standard-Iterator-Schnittstelle eine ListIterator-Schnittstelle zurückgibt mehr Einige Methoden wie add() ermöglichen das Hinzufügen, Löschen, Festlegen von Elementen und das Vorwärts- oder Rückwärtslaufen.
Gemeinsame Klassen, die die List-Schnittstelle implementieren, sind LinkedList, ArrayList, Vector und Stack.
LinkedList implementiert die List-Schnittstelle und lässt Nullelemente zu. Darüber hinaus bietet LinkedList zusätzliche Get-, Remove- und Insert-Methoden. Diese Operationen ermöglichen die Verwendung von LinkedList als Stack, Warteschlange oder Deque.
Beachten Sie, dass LinkedList keine Synchronizität aufweist . Wenn mehrere Threads gleichzeitig auf eine LinkedList zugreifen, müssen Sie die Zugriffssynchronisierung selbst implementieren. Eine andere Lösung besteht darin, beim Erstellen der Liste eine synchronisierte Liste zu erstellen: List list = Collections.synchronizedList(new LinkedList(...));
ArrayList implementiert ein Array variabler Größe. Es erlaubt alle Elemente, einschließlich null. ArrayList hat keine Synchronizität.
Die Laufzeit der Methoden size, isEmpty, get, set ist konstant. Allerdings sind die Kosten der Add-Methode eine amortisierte Konstante, und das Addieren von n Elementen erfordert O(n) Zeit. Andere Methoden haben eine lineare Laufzeit.
Jede ArrayList-Instanz verfügt über eine Kapazität (Capacity), die der Größe des Arrays entspricht, das zum Speichern von Elementen verwendet wird. Diese Kapazität erhöht sich automatisch, wenn neue Elemente hinzugefügt werden, der Wachstumsalgorithmus ist jedoch nicht definiert. Wenn eine große Anzahl von Elementen eingefügt werden muss, kann die Methode „sichsureCapacity“ aufgerufen werden, um die Kapazität der ArrayList vor dem Einfügen zu erhöhen und so die Einfügeeffizienz zu verbessern.
Vector ist ArrayList sehr ähnlich, aber Vector ist synchronisiert. Obwohl der von Vector erstellte Iterator dieselbe Schnittstelle hat wie der von ArrayList erstellte Iterator, weil Vector synchronisiert ist, ändert ein anderer Thread den Status des Vectors, wenn ein Iterator erstellt und verwendet wird (z. B. indem er ein Element hinzufügt oder entfernt). , ConcurrentModificationException wird beim Aufruf der Iterator-Methode ausgelöst, daher muss die Ausnahme abgefangen werden.
Stack erbt von Vector und implementiert einen Last-In-First-Out-Stack. Stack bietet 5 zusätzliche Methoden, mit denen Vector als Stack verwendet werden kann. Die grundlegenden Push- und Pop-Methoden sowie die Peek-Methode holen sich das Element oben im Stapel, die leere Methode testet, ob der Stapel leer ist, und die Suchmethode erkennt die Position eines Elements im Stapel. Der Stapel ist nach seiner Erstellung ein leerer Stapel.
1. Vector ist threadsynchronisiert, also auch threadsicher, während ArrayList und LinkedList sind nicht Thread-sicher. Wenn Thread-Sicherheitsfaktoren nicht berücksichtigt werden, ist es im Allgemeinen effizienter, ArrayList und LinkedList zu verwenden.
2. ArrayList und Vector implementieren Datenstrukturen basierend auf dynamischen Arrays, und LinkedList basiert auf Datenstrukturen verknüpfter Listen.
3. Wenn die Anzahl der Elemente in der Sammlung größer ist als die Länge des aktuellen Sammlungsarrays, beträgt die Vektorwachstumsrate 100 % der aktuellen Arraylänge und die ArrayList-Wachstumsrate Die Rate beträgt 50 % der aktuellen Array-Länge. Wenn Sie eine relativ große Datenmenge in der Sammlung verwenden, bietet die Verwendung von ArrayList bestimmte Vorteile.
3. Wenn Daten an einem bestimmten Ort findet, ist die von Vector und ArrayList benötigte Zeit gleich und die aufgewendete Zeit beträgt O(1), while LinkedList muss durchlaufen werden. Die Suche dauert O(i) Zeit und ist nicht so effizient wie die ersten beiden.
Verschieben oder Löschen von Daten an einem bestimmten Ort 0(n-i) dauert, sollten Sie zu diesem Zeitpunkt die Verwendung von LinkedList in Betracht ziehen Die zum Verschieben von Daten an einem bestimmten Ort benötigte Zeit beträgt 0(1).
Daten am angegebenen Ort hat LinedList den Vorteil, da ArrayList Daten verschieben muss.
Bitte beachten Sie: Veränderliche Objekte müssen mit Vorsicht behandelt werden. Wenn ein veränderliches Element in einem Set seinen Zustand ändert und Object.equals(Object)=true verursacht, führt dies zu einigen Problemen.
Die Map-Schnittstelle bietet drei Arten von Satzansichten. Der Inhalt der Karte kann als Satz von Schlüsselsätzen, Satz von Wertsätzen oder Satz von Schlüsselwertzuordnungen betrachtet werden.
Hashtable erbt die Map-Schnittstelle und implementiert eine Schlüsselwertzuordnung Hash-Tabelle. Jedes Nicht-Null-Objekt kann als Schlüssel oder Wert verwendet werden.
Um Daten hinzuzufügen, verwenden Sie put(key, value) und um Daten zu entfernen, verwenden Sie get(key). Der Zeitaufwand dieser beiden Grundoperationen ist konstant.
Hashtable passt die Leistung über zwei Parameter an: Anfangskapazität und Auslastungsfaktor. Normalerweise erreicht der Standardlastfaktor 0,75 ein besseres Gleichgewicht zwischen Zeit und Raum. Durch Erhöhen des Auslastungsfaktors kann Platz gespart werden, die entsprechende Suchzeit erhöht sich jedoch, was sich auf Vorgänge wie „Abrufen“ und „Put“ auswirkt.
Da das als Schlüssel verwendete Objekt die Position des entsprechenden Werts durch Berechnung seiner Hash-Funktion bestimmt, muss jedes als Schlüssel verwendete Objekt die Methoden hashCode und equal implementieren. Die Methoden hashCode und equal werden von der Stammklasse Object geerbt.
Hashtable ist synchron.
HashMap ähnelt Hashtable, mit der Ausnahme, dass HashMap asynchron ist und Null zulässig, also Nullwert und Nullschlüssel. Wenn HashMap jedoch als Sammlung behandelt wird (die Methode „values()“ kann eine Sammlung zurückgeben), ist der Zeitaufwand für die Iterationsunteroperationen proportional zur Kapazität der HashMap. Wenn die Leistung iterativer Operationen sehr wichtig ist, sollten Sie daher die Anfangskapazität von HashMap nicht zu hoch oder den Auslastungsfaktor zu niedrig einstellen.
HashMap verwendet Hashcode, um seinen Inhalt schnell und ungeordnet zu durchsuchen Alle Elemente in TreeMap behalten eine bestimmte feste Reihenfolge bei und sind geordnet.
HashMap ist die beste Wahl zum Einfügen, Löschen und Positionieren von Elementen in Map. Wenn Sie jedoch Schlüssel in natürlicher oder benutzerdefinierter Reihenfolge durchlaufen möchten, ist TreeMap besser geeignet. Die Verwendung von HashMap erfordert, dass die hinzugefügte Schlüsselklasse die Implementierung von hashCode() und equal() klar definiert.
TreeMap hat keine Optimierungsoptionen, da sich der Baum immer in einem ausgeglichenen Zustand befindet.
WeakHashMap ist eine verbesserte HashMap, die eine „schwache Referenz“ für den Schlüssel If If a implementiert Der Schlüssel wird nicht mehr extern referenziert, der Schlüssel kann von GC recycelt werden.
Wenn es sich um Vorgänge mit Stapeln, Warteschlangen usw. handelt, sind Sie Sie sollten die Verwendung von List in Betracht ziehen. Wenn Sie Elemente schnell einfügen und löschen müssen, sollten Sie LinkedList verwenden. Wenn Sie schnell auf Elemente zugreifen müssen, sollten Sie ArrayList verwenden.
Wenn sich das Programm in einer Single-Thread-Umgebung befindet oder der Zugriff nur in einem Thread erfolgt, sollten Sie asynchrone Klassen in Betracht ziehen, die effizienter sind, wenn mehrere Threads eine Klasse gleichzeitig betreiben können Gleichzeitig sollten synchronisierte Klassen verwendet werden.
Achten Sie besonders auf die Funktionsweise der Hash-Tabelle. Die Methoden equal und hashCode müssen als Schlüsselobjekt korrekt überschrieben werden.
Bei Verwendung von Map ist es am besten, HashMap oder HashTable zum Suchen, Aktualisieren, Löschen und Hinzufügen zu verwenden, wenn Map in natürlicher Reihenfolge oder in benutzerdefinierter Schlüsselreihenfolge durchlaufen wird TreeMap;
Versuchen Sie, die Schnittstelle anstelle des tatsächlichen Typs zurückzugeben, z. B. indem Sie List anstelle von ArrayList zurückgeben. Wenn Sie ArrayList in Zukunft durch LinkedList ersetzen müssen, wird der Client-Code verwendet muss sich nicht ändern. Das ist Programmierung zur Abstraktion.
Das obige ist der detaillierte Inhalt vonEinführung in die Verwendung des Java-Frameworks. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!