Sammlungen in Java konzentrieren sich hauptsächlich auf zwei Teile: Der eine befindet sich im Paket java.util und der andere im Paket java.util.concurrent. Letzterer basiert auf dem ersteren und definiert einige Sammlungen, die Synchronisationsfunktionen implementieren.
Dieser Artikel konzentriert sich hauptsächlich auf verschiedene Sammlungsobjekte unter java.util. Sammlungsobjekte in Java können grob in drei Kategorien unterteilt werden: Liste, Menge und Karte. Das entsprechende UML-Diagramm lautet wie folgt (einschließlich der meisten Sammlungsobjekte unter java.util):
Sammlungsübersicht
Sowohl List- als auch Set-in-Java-Sammlungen stammen aus Collection. Sie sind ein guter Einstiegspunkt für das Erlernen von Sammlungen. Sie umfassen Vorgänge, die normalerweise in Sammlungen erforderlich sind.
Elemente hinzufügen: add/addAll
Sammlung löschen: löschen
Elemente entfernen: Remove/RemoveAll
Bestimmen Sie, ob die Sammlung ein Element enthält: enthält/containsAll
Bestimmen Sie, ob die Sammlung leer ist: isEmpty
Berechnen Sie die Anzahl der Elemente in einer Sammlung: Größe
Konvertieren Sie eine Sammlung in ein Array: toArray
Holen Sie sich Iterator: Iterator
Schauen wir uns ein einfaches Beispiel an. Der folgende Code gibt eine Sammlung zurück, deren Elemente zufällig generierte Ganzzahlen sind:
Rücknahme;
}
1) Verwenden Sie Iteratoren, um die Sammlung zu durchlaufen. Wie oben bei der Beschreibung der Collection-Schnittstelle erwähnt, verfügen alle Collections über einen Iterator, den wir zum Durchlaufen der Collection verwenden können.
Liste in Java ist eine effektive Erweiterung des Arrays. Es handelt sich um eine Struktur, die Elemente jedes Typs enthalten kann, wenn keine Generika verwendet werden. Wenn Generika verwendet werden, kann sie nur Elemente des durch die Generika angegebenen Typs enthalten. Im Vergleich zu Arrays kann die Kapazität von List dynamisch erweitert werden.
Die Elemente in der Liste können wiederholt werden und die darin enthaltenen Elemente sind „geordnet“. Das „geordnet“ bedeutet hier nicht Sortieren, sondern bedeutet, dass wir die Position eines Elements in der Sammlung angeben können.
Zu den häufig verwendeten Sammlungsobjekten in List gehören: ArrayList, Vector und LinkedList. Die beiden ersteren werden basierend auf Arrays und die letzteren basierend auf verknüpften Listen gespeichert. Unter diesen ist Vector Thread-sicher und die anderen beiden sind nicht Thread-sicher.
Die Liste kann Null enthalten, auch wenn Generika verwendet werden.
ArrayList ist möglicherweise das am häufigsten verwendete Sammlungsobjekt. Im obigen Beispielcode verwenden wir es auch, um ein Sammlungsobjekt zu instanziieren, daher gehen wir hier nicht auf Details ein.
Vektor
Ein Beispiel für Vector ist wie folgt. Zuerst schauen wir uns an, wie man Vector generiert und ausgibt:
[9, 29, 32, 54, 12]
Die Größe des Vektors beträgt 3
[29, 32, 54]
LinkedList verwendet verknüpfte Listen zum Speichern von Daten. Der Beispielcode lautet wie folgt:
Die Ausgabe ist wie folgt:
null
null
null
Die Größe der verknüpften Liste beträgt 8
[100, 84, 19, 57, 68, 26, 27, 47]
Set ähnelt List, beide werden zum Speichern eines einzelnen Elements verwendet und die Anzahl der einzelnen Elemente ist ungewiss. Set kann jedoch keine doppelten Elemente enthalten. Wenn zwei identische Elemente in Set eingefügt werden, wird das letztere Element nicht eingefügt.
Das Set kann grob in zwei Kategorien unterteilt werden: unsortiertes Set und sortiertes Set. Unsortiertes Set umfasst HashSet und LinkedHashSet, und sortiertes Set bezieht sich hauptsächlich auf TreeSet. Unter diesen können HashSet und LinkedHashSet null enthalten.
HashSet
HashSet ist eine Sammlung, die von einer Hash-Tabelle unterstützt wird, die nicht threadsicher ist.
Schauen wir uns das folgende Beispiel an, das im Grunde mit dem ersten Beispiel mit Vector identisch ist:
for (int i = 0; i < 3; i++)
{
set.add(new Integer(100));
}
set.add(null);
System.out.println("Größe des Satzes ist " + set.size());
System.out.println(set);
}
classMyInteger
{
privater Ganzzahlwert;
public MyInteger(Integer-Wert)
{
this.value = value;
}
öffentlicher String toString()
{
return String.valueOf(value);
}
public int hashCode()
{
Rückgabe 1;
}
öffentlicher boolescher Wert gleicht (Objekt obj)
{
return true;
}
}
Das Folgende ist die entsprechende Testmethode:
for (int i = 0; i < 3; i++)
{
set.add(new MyInteger(100));
}
System.out.println("Größe des Satzes ist " + set.size());
System.out.println(set);
}
TreeSet ist ein Set, das das Sortieren unterstützt, und seine übergeordnete Schnittstelle ist SortedSet.
Werfen wir zunächst einen Blick auf die Grundfunktionen von TreeSet:
Zufällig r = new Random();
for (int i = 0; i < 5; i++)
{
set.add(new Integer(r.nextInt(100)));
}
System.out.println(set);
System.out.println(set.first());
System.out.println(set.last());
System.out.println(set.descendingSet());
System.out.println(set.headSet(new Integer(50)));
System.out.println(set.tailSet(new Integer(50)));
System.out.println(set.subSet(30, 60));
System.out.println(set.floor(50));
System.out.println(set.ceiling(50));
}
[53, 49, 48, 42, 8]
[8, 42, 48, 49]
[53]
[42, 48, 49, 53]
Als nächstes definieren wir zunächst Integer neu:
public MyInteger2(int value)
{
this.value = value;
}
public int CompareTo(Object arg0)
{
MyInteger2 temp = (MyInteger2)arg0;
if (temp == null) return -1;
if (temp.value > this.value)
{
Rückgabe 1;
}
sonst wenn (temp.value < this.value)
{
return -1;
}
0 zurückgeben;
}
öffentlicher boolescher Wert gleicht (Objekt obj)
{
return vergleichenTo(obj) == 0;
}
öffentlicher String toString()
{
return String.valueOf(value);
}
}
Map speichert „Schlüssel-Wert-Paare“. Ähnlich wie bei Set gibt es in Java zwei Arten von Maps: sortierte und unsortierte Maps umfassen HashMap, Hashtable und LinkedHashMap, und sortierte umfassen TreeMap.
Unsortierte Karte
Sowohl HashMap als auch Hashtable werden in Form von Hash-Tabellen gespeichert. HashMap ist nicht threadsicher, Hashtable ist jedoch threadsicher. Wir können HashMap als eine „vereinfachte“ Version von Hashtable betrachten.
HashMap kann Nullen speichern, unabhängig davon, ob es sich um einen Schlüssel oder einen Wert handelt. Hashtable kann keine Nullen speichern.
Unabhängig von HashMap oder Hashtable werden wir bei Beobachtung des Konstruktors feststellen, dass er zwei Parameter haben kann: initialCapacity und LoadFactor. Standardmäßig ist initialCapacity gleich 16 und LoadFactor gleich 0,75. Dies hängt mit der Anzahl der Elemente zusammen, die in der Hash-Tabelle gespeichert werden können. Wenn die Anzahl der Elemente initialCapacity*loadFactor überschreitet, wird die Rehash-Methode ausgelöst, um die Hash-Tabelle zu erweitern. Wenn wir zu viele Elemente einfügen müssen, müssen wir diese beiden Parameter entsprechend anpassen.
Schauen wir uns zunächst ein Beispiel von HashMap an:
map.put(new Integer(1), "a");
map.put(new Integer(2), "b");
map.put(new Integer(3), "c");
System.out.println(map);
System.out.println(map.entrySet());
System.out.println(map.keySet());
System.out.println(map.values());
}
map.put(null, null);
map.put(null, null);
map.put(new Integer(4), null);
map.put(new Integer(5), null);
System.out.println(map);
System.out.println(map.entrySet());
System.out.println(map.keySet());
System.out.println(map.values());
}
table.put(new Integer(1), "a");
table.put(new Integer(2), "b");
table.put(new Integer(3), "c");
System.out.println(table);
System.out.println(table.entrySet());
System.out.println(table.keySet());
System.out.println(table.values());
}
private static void hashTableTest2()
{
Map<Integer,String> table = new Hashtable<Integer, String>();
table.put(null, null);
table.put(null, null);
table.put(new Integer(4), null);
table.put(new Integer(5), null);
System.out.println(table);
System.out.println(table.entrySet());
System.out.println(table.keySet());
System.out.println(table.values());
}
Sorting Map bezieht sich hauptsächlich auf TreeMap, das beim Hinzufügen, Löschen und Suchen von Elementen eine zeitliche Komplexität von O(log(n)) aufweist. Es ist nicht threadsicher.
Seine Eigenschaften sind denen von TreeSet sehr ähnlich, daher werde ich hier nicht auf Details eingehen.