Java Collection Framework

Bereits vor Java 2 stellte Java Ad-hoc-Klassen bereit. Zum Beispiel: Dictionary, Vector, Stack und Properties; diese Klassen wurden verwendet, um Gruppen von Objekten zu speichern und zu bearbeiten.

Obwohl diese Klassen sehr nützlich sind, fehlt ihnen ein zentrales, einheitliches Konzept. Aus diesem Grund unterscheidet sich die Verwendung der Klasse Vector erheblich von der Verwendung der Klasse Properties.

Das Collection-Framework wurde entworfen, um die folgenden Ziele zu erfüllen.

  • Das Framework muss hochperformant sein. Auch die Implementierungen grundlegender Sammlungen (dynamische Arrays, verkettete Listen, Bäume, Hash-Tabellen) müssen effizient sein.

  • Das Framework ermöglicht es verschiedenen Arten von Sammlungen, auf ähnliche Weise zu funktionieren, mit einem hohen Grad an Interoperabilität.

  • Erweiterungen und Anpassungen einer Sammlung müssen einfach sein.

Zu diesem Zweck ist das gesamte Collection-Framework um eine Reihe von Standardschnittstellen herum entworfen. Sie können die Standardimplementierungen dieser Schnittstellen direkt verwenden, wie zum Beispiel:LinkedList, HashSet, undTreeSet, usw. Darüber hinaus können Sie auch Ihre eigenen Sammlungen über diese Schnittstellen implementieren.

Aus dem obigen Collection-Framework-Diagramm ist ersichtlich, dass das Java-Collection-Framework hauptsächlich zwei Arten von Containern umfasst: eine ist Collection, die eine Sammlung von Elementen speichert; die andere ist Map, die Schlüssel/Wert-Paar-Zuordnungen speichert. Die Collection-Schnittstelle hat 3 Untertypen: List, Set und Queue. Darunter befinden sich einige abstrakte Klassen und schließlich konkrete Implementierungsklassen. Häufig verwendete sind unter anderemArrayList、LinkedList、HashSet、LinkedHashSet, HashMap, LinkedHashMap und so weiter.

Das Collection-Framework ist eine einheitliche Architektur zur Darstellung und Manipulation von Collections. Alle Collection-Frameworks enthalten Folgendes:

  • Schnittstellen:

    Dies sind abstrakte Datentypen, die Collections repräsentieren. Zum Beispiel: Collection, List, Set, Map usw. Der Grund, warum mehrere Schnittstellen definiert werden, besteht darin, Collection-Objekte auf unterschiedliche Weise zu manipulieren.
  • Implementierungen (Klassen):Dies sind konkrete Implementierungen der Collection-Schnittstellen. Im Wesentlichen sind sie wiederverwendbare Datenstrukturen, zum Beispiel: ArrayList, LinkedList, HashSet, HashMap.

  • Algorithmen:Dies sind einige nützliche Berechnungen, die von Methoden in Objekten ausgeführt werden, die Collection-Schnittstellen implementieren, zum Beispiel: Suchen und Sortieren. Diese Algorithmen erreichen Polymorphismus, weil dieselbe Methode unterschiedliche Implementierungen für ähnliche Schnittstellen haben kann.

Zusätzlich zu Collections definiert das Framework auch mehrere Map-Schnittstellen und -Klassen. Maps speichern Schlüssel/Wert-Paare. Obwohl Maps keine Collections sind, sind sie vollständig in Collections integriert.

Das System des Collection-Frameworks ist in der folgenden Abbildung dargestellt.

Das Java-Collection-Framework bietet eine Reihe leistungsfähiger, benutzerfreundlicher Schnittstellen und Klassen. Das Java-Collection-Framework befindet sich im Paket java.util, daher müssen Sie das Paket importieren, wenn Sie das Collection-Framework verwenden.


Collection-Schnittstellen

Das Collection-Framework definiert einige Schnittstellen. Dieser Abschnitt bietet einen Überblick über jede Schnittstelle:

Nein. Schnittstelle Beschreibung
1 Collection-Schnittstelle

Collection ist die grundlegendste Collection-Schnittstelle. Eine Collection repräsentiert eine Gruppe von Objekten, d. h. die Elemente der Collection. Java stellt keine Klassen bereit, die direkt von Collection erben; es stellt nur Subinterfaces bereit, die davon erben (wie List und Set).

Die Collection-Schnittstelle speichert eine Gruppe von nicht eindeutigen, ungeordneten Objekten.

2 List-Schnittstelle

Die List-Schnittstelle ist eine geordnete Collection. Mit dieser Schnittstelle können Sie die Position, an der jedes Element eingefügt wird, präzise steuern und auf Elemente in der List über den Index zugreifen (die Position des Elements in der List, ähnlich einem Array-Index). Das erste Element hat den Index 0, und doppelte Elemente sind zulässig.

Die List-Schnittstelle speichert eine Gruppe von nicht eindeutigen, geordneten (Einfügereihenfolge) Objekten.

3 Set

Set hat genau dieselbe Schnittstelle wie Collection, verhält sich jedoch anders; Set speichert keine doppelten Elemente.

Die Set-Schnittstelle speichert eine Gruppe von eindeutigen, ungeordneten Objekten.

4 SortedSet
Erbt von Set und speichert eine geordnete Collection.
5 Map

Die Map-Schnittstelle speichert eine Gruppe von Schlüssel-Wert-Objekten und bietet eine Zuordnung von Schlüssel zu Wert.

6 Map.Entry
Beschreibt ein Element (Schlüssel/Wert-Paar) in einer Map. Es ist eine innere Schnittstelle von Map.
7 SortedMap
Erbt von Map und hält die Schlüssel in aufsteigender Reihenfolge.
8 Enumeration
Dies ist eine Legacy-Schnittstelle, die Methoden definiert, mit denen Elemente in einer Sammlung von Objekten aufgezählt werden können (einzeln abgerufen). Diese Legacy-Schnittstelle wurde durch Iteratoren ersetzt.

Unterschiede zwischen Set und List

  • 1. Instanzen der Set-Schnittstelle speichern ungeordnete, nicht doppelte Daten. Instanzen der List-Schnittstelle speichern geordnete, wiederholbare Elemente.

  • 2. Set hat eine geringe Abrufeffizienz, aber eine hohe Lösch- und Einfügeeffizienz; Einfügen und Löschen verursachen keine Änderungen der Elementposition.<Implementierungsklassen umfassen HashSet, TreeSet>。

  • 3. List ist einem Array ähnlich und kann dynamisch wachsen; die Länge der List erhöht sich automatisch entsprechend der Länge der tatsächlich gespeicherten Daten. Sie ist effizient beim Finden von Elementen und wenig effizient beim Einfügen und Löschen, weil sie Positionsänderungen anderer Elemente verursacht.<Implementierungsklassen umfassen ArrayList, LinkedList, Vector> 。


Collection-Implementierungsklassen (Collection-Klassen)

Java stellt eine Reihe von Standard-Collection-Klassen bereit, die die Collection-Schnittstelle implementieren. Einige davon sind konkrete Klassen und können direkt verwendet werden, während andere abstrakte Klassen sind, die Teilimplementierungen der Schnittstelle bereitstellen.

Die Standard-Collection-Klassen sind in der folgenden Tabelle zusammengefasst:

Nein. Klassenbeschreibung
1 AbstractCollection 
Implementiert die meisten der Collection-Schnittstellen.
2 AbstractList 
Erbt von AbstractCollection und implementiert den Großteil der List-Schnittstelle.
3 AbstractSequentialList 
Erbt von AbstractList und bietet verketteten Zugriff auf Datenelemente statt wahlfreien Zugriff.
4 LinkedList

Diese Klasse implementiert die List-Schnittstelle und erlaubt null-Elemente. Sie wird hauptsächlich zum Erstellen von verketteten Listen-Datenstrukturen verwendet. Diese Klasse hat keine synchronisierten Methoden. Wenn mehrere Threads gleichzeitig auf eine List zugreifen, müssen Sie die Zugriffssynchronisierung selbst implementieren. Die Lösung besteht darin, beim Erstellen der List eine synchronisierte List zu konstruieren. Zum Beispiel:

List list=Collections.synchronizedList(newLinkedList(...));

LinkedList hat eine geringe Nachschlageeffizienz.

5 ArrayList

Diese Klasse implementiert ebenfalls die List-Schnittstelle und implementiert ein Array variabler Größe, was eine bessere Leistung beim wahlfreien Zugriff auf und Durchlaufen von Elementen bietet. Diese Klasse ist ebenfalls nicht synchronisiert und sollte nicht in Multithread-Situationen verwendet werden. ArrayList wächst um 50 % ihrer aktuellen Länge, und die Effizienz beim Einfügen/Löschen ist gering.

6 AbstractSet 
Erbt von AbstractCollection und implementiert den Großteil der Set-Schnittstelle.
7 HashSet

Diese Klasse implementiert die Set-Schnittstelle. Doppelte Elemente sind nicht erlaubt, die Reihenfolge der Elemente im Set ist nicht garantiert, und Elemente mit dem Wert null sind erlaubt, aber höchstens eines.

8 LinkedHashSet
Verfügt über eine vorhersagbare IterationsreihenfolgeSetDie Implementierung der Schnittstelle mit Hash-Tabelle und verknüpfter Liste.
9 TreeSet

Diese Klasse implementiert die Set-Schnittstelle und kann Sortierung und andere Funktionen implementieren.

10 AbstractMap 
Implementiert den Großteil der Map-Schnittstelle.
11 HashMap
HashMap ist eine Hash-Tabelle; ihr gespeicherter Inhalt sind Schlüssel-Wert-Paar-Zuordnungen.
Diese Klasse implementiert das Map-Interface, speichert Daten gemäß dem HashCode-Wert des Schlüssels, hat eine sehr schnelle Zugriffsgeschwindigkeit, erlaubt höchstens einen Datensatz mit einem null-Schlüssel und unterstützt keine Thread-Synchronisierung.
12 TreeMap
Erbt von AbstractMap und verwendet einen Baum.
13 WeakHashMap
Erbt von der Klasse AbstractMap und verwendet eine Hash-Tabelle mit schwachen Schlüsseln.
14 LinkedHashMap
Erbt von HashMap und sortiert Elemente unter Verwendung ihrer natürlichen Ordnung.
15 IdentityHashMap
Erbt von der Klasse AbstractMap und verwendet Referenzgleichheit beim Vergleichen von Dokumenten.

Früher im Tutorial wurden die im Paket java.util definierten Klassen besprochen, wie unten gezeigt:

Nein. Klassenbeschreibung
1 Vektor

Diese Klasse ist der ArrayList sehr ähnlich, aber diese Klasse ist synchronisiert und kann in Multithread-Situationen verwendet werden. Diese Klasse erlaubt das Festlegen der standardmäßigen Wachstumslänge, und die standardmäßige Erweiterungsmethode ist 2-mal das Original.

2 Stapel
Stack ist eine Unterklasse von Vector; er implementiert einen standardmäßigen Last-In-First-Out-Stack.
3 Wörterbuch
Die Klasse Dictionary ist eine abstrakte Klasse, die zum Speichern von Schlüssel/Wert-Paaren verwendet wird, und ihre Funktion ähnelt der Klasse Map.
4 Hashtable

Hashtable ist eine Unterklasse der Klasse Dictionary und befindet sich im Paket java.util.

5 Eigenschaften
Properties erbt von Hashtable und repräsentiert eine persistente Menge von Eigenschaften. In der Eigenschaftsliste sind jeder Schlüssel und sein entsprechender Wert Zeichenketten.
6 BitSet
Eine BitSet-Klasse erstellt einen speziellen Typ von Array zum Speichern von Bitwerten. Die Größe des Arrays in BitSet wird bei Bedarf erhöht.

Sammlungsalgorithmen

Das Collection-Framework definiert mehrere Algorithmen, die auf Collections und Maps angewendet werden können. Diese Algorithmen sind als statische Methoden von Collection-Klassen definiert.

Beim Versuch, inkompatible Typen zu vergleichen, können einige Methoden eine ClassCastException auslösen. Beim Versuch, eine nicht änderbare Collection zu ändern, wird eine UnsupportedOperationException ausgelöst.

Die Collections definieren drei statische Variablen: EMPTY_SET, EMPTY_LIST und EMPTY_MAP. Diese Variablen sind alle unveränderlich.

Lfd. Nr. Algorithmusbeschreibung
1 Sammlungsalgorithmen
Hier ist eine Liste aller Algorithmusimplementierungen.

Wie man Iteratoren verwendet

Normalerweise möchten Sie die Elemente in einer Sammlung durchlaufen. Zum Beispiel: jedes Element in der Sammlung anzeigen.

Im Allgemeinen wird beim Durchlaufen von Arrays eine for-Schleife oder eine erweiterte for-Schleife verwendet. Diese beiden Methoden können auch im Collection-Framework verwendet werden, aber es gibt eine weitere Methode, die einen Iterator verwendet, um das Collection-Framework zu durchlaufen. Es ist ein Objekt, das dieIteratorIterator-Schnittstelle oder die ListIterator-Schnittstelle.

Iteratoren ermöglichen es Ihnen, Collection-Elemente in einer Schleife abzurufen oder zu löschen. ListIterator erbt von Iterator, um eine bidirektionale Durchquerung von Listen und die Änderung von Elementen zu ermöglichen.

Lfd. Nr. Iterator-Methodenbeschreibung
1 Java-Iterator verwenden
Hier werden anhand von Beispielen alle Methoden aufgeführt, die von den Iterator- und ListIterator-Schnittstellen bereitgestellt werden.

ArrayList durchlaufen

Beispiel

import java.util.*; public class Test{ public static void main(String[] args) { List<String> list=new ArrayList<String>(); list.add("Hello"); list.add("World"); list.add("HAHAHAHA"); //Die erste Traversierungsmethode verwendet For-Each, um die List zu durchlaufen. for (String str : list) { //Es kann auch in der Form for(int i=0;i<list.size();i++) umgeschrieben werden System.out.println(str); } //Die zweite Traversierung wandelt die Liste in einen array-bezogenen Inhalt für die Traversierung um. String[] strArray=new String[list.size()]; list.toArray(strArray); for(int i=0;i<strArray.length;i++) //Es kann auch in der Form for(String str:strArray) umgeschrieben werden { System.out.println(strArray[i]); } //Die dritte Traversierung verwendet einen Iterator für die relevante Traversierung. Iterator<String> ite=list.iterator(); while(ite.hasNext())//Bestimme, ob nach dem nächsten Element ein Wert vorhanden ist. { System.out.println(ite.next()); } } }

Analyse:

Alle drei Methoden werden zum Durchlaufen der ArrayList-Sammlung verwendet. Die dritte Methode verwendet einen Iterator, wodurch man sich keine Gedanken über das Überschreiten der Länge der Sammlung während des Durchlaufens machen muss.

Map durchlaufen

Beispiel

import java.util.*; public class Test{ public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("1", "value1"); map.put("2", "value2"); map.put("3", "value3"); //Zuerst: häufig verwendet, den Wert ein zweites Mal abrufen. System.out.println("Schlüssel und Wert über Map.keySet durchlaufen:"); for (String key : map.keySet()) { System.out.println("key= "+ key + " and value= " + map.get(key)); } //Zweitens System.out.println("Verwenden Sie einen Iterator über Map.entrySet, um Schlüssel und Wert zu durchlaufen:"); Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } //Drittens: empfohlen, insbesondere wenn die Kapazität groß ist. System.out.println("Durchlaufen Sie Schlüssel und Wert über Map.entrySet"); for (Map.Entry<String, String> entry : map.entrySet()) { System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } //Viertens System.out.println("Alle Werte über Map.values() durchlaufen, aber Schlüssel können nicht durchlaufen werden."); for (String v : map.values()) { System.out.println("value= " + v); } } }


Verwendung von Comparator-Objekten

TreeSet und TreeMap speichern Elemente in sortierter Reihenfolge. Allerdings ist es ein Comparator, der genau definiert, welche Sortierreihenfolge verwendet wird.

Diese Schnittstelle ermöglicht es uns, eine Sammlung auf unterschiedliche Weise zu sortieren.

Lfd. Nr. Comparator-Methodenbeschreibung
1 Verwendung von Java Comparator
Hier werden anhand von Beispielen alle Methoden aufgeführt, die die Comparator-Schnittstelle bereitstellt.

Zusammenfassung

Das Java Collections Framework bietet Programmierern vorgefertigte Datenstrukturen und Algorithmen, um sie zu manipulieren.

Eine Collection ist ein Objekt, das Referenzen auf andere Objekte halten kann. Die Collection-Schnittstellen deklarieren die Operationen, die für jeden Collection-Typ ausgeführt werden können.

Die Klassen und Schnittstellen des Collections Frameworks befinden sich alle im Paket java.util.

Nachdem ein beliebiges Objekt zu einer Collection-Klasse hinzugefügt wurde, wird es automatisch in den Typ Object konvertiert; wenn es abgerufen wird, ist daher eine erzwungene Typkonvertierung erforderlich.

Andere Erweiterungen