Überblick Java Collections

Überblick Java Collections

Die Klassen des Java Collection Framework in java.util stellen vier Familien von abstrakten Datentypen und Funktionen zur Verfügung:

  • Listen (abstrakte Klasse List): geordnete Datenstrukturen auf die man wie auf Felder mit einem numerischen Index zugreifen kann. Im Unterschied zu Feldern (Array) erlauben sie das listentypische Einfügen an einer beliebigen Stelle
  • Mengen (abstrakte Klasse Set): Eine Implementierung mathematischer Mengen. Objekte können nur einmal in einer Menge vorkommen. Man kann prüfen ob bestimmte Objekte in einer Menge enthalten sind. Eine Reihenfolge oder Ordnung in der Menge ist nicht relevant.
  • Verzeichnisse (abstrakte Klasse Map): Verzeichnisse können als verallgemeinerte Felder angesehen werden. Felder erlauben einen direkten zugriff mit einem numerischen Index. Verzeichnisse erlauben die Wahl einer beliebigen Zugriffskriteriums. Man kann zum Beispiel Personen nach ihrem Nachnamen verwalten und eine Person mit Hilfe eines gegebenen Nachnamens aurufen.
  • Warteschlangen (abstrakte Klasse Queue): Warteschlangen sind Listen die nach dem FIFO Prinzip (First In , First Out) aufgebaut sind. Sie verfügen über keinen wahlfreien Zugriff.

Hinzu kommt die Hilfsklasse Arrays zum Verwalten von Feldern. Die Klasse fasst viele nützliche statische Methoden zum Suchen und Sortieren von Feldern zusammen. Die Klasse Arrays gehört zu diesem Paket, da Felder logisch zu den abstrakten Datentypen gehören. Da Felder wegen der benötigten Effizienz  ein Hybrid zwischen Basistypen und komplexen Typen sind, passen Sie nicht sauber in die hier vorgestellte Vererbunghierarchie.

Die vier Familien werden durch die folgende Hierarchie von Schnittstellen in Java implementiert:

Jede dieser Familien wird durch eine abstrakte Klasse und eine Schnittstelle implementiert. Die Aufteilung in diese beiden Aspekte findet nach dem folgenden Prinzip statt:

  • Schnittstelle: Sie definiert welche Operationen für eine bestimmte Familie erlaubt sind (funktionale Eigenschaft). Diese funktionalen Eigenschaften sind:
    • sortiert oder unsortiert
    • geordnet oder ungeordnet. Bleibt die Einfügereihenfolge erhalten?
    • sequenziell oder wahlfreier Zugriff
  • abstrakte Basisklasse: Die abstrakte Klasse implementiert die Schnittstelle und bestimmt damit den Algorithmus, der zu einer bestimmten Effizienz führt.

Zur Auswahl der optimalen Klasse kann man sich an der folgenden Tabelle von Klassen und Eigenschaften orientieren:

Klassen des Java Collection Frameworks
Klasse Famlie (implem. Schnittst.) Zugriff Duplikate erlaubt Ordnung Kommentar
ArrayList Liste(List) wahlfrei über Index Ja geordnet effizientes Lesen über Index
LinkedList Liste(List) wahlfrei über Index Ja geordnet  effizientes Einfügen
Vector Liste(List) wahlfrei über Index Ja geordnet  synchronisiert(!) 
Stack Liste(List) sequentiell (letztes Element) Ja geordnet  LIFO: Last In First Out
HashSet   Menge(Set) ungeordnet; Test auf Existenz Nein ungeordnet schnelles Lesen, Einfügen, Löschen
TreeSet   Menge(Set) sortiert; Test auf Existenz Nein sortiert   
LinkedList Warteschlange(Queue)  sequentiell, Nachfolger Ja  geordnet  effizientes Einfügen (am Rand) 
PriorityQueue  Warteschlange(Queue)  sequentiell, Nachfolger  Ja  sortiert   
HashMap  Verzeichnis(Map)  wahlfrei über Schlüssel  Keine Schlüsselduplikate, Werteduplikate erlaubt  ungeordnet  effizientes Lesen, Einfügen, Löschen
TreeMap  Verzeichnis(Map)  wahlfrei über Schlüssel  Keine Schlüsselduplikate, Werteduplikate erlaubt  sortiert  

 In Bezug auf die Spalte Ordnung:

  • geordnet: Elemente tauchen beim Iterieren in der gleichen Reihenfolge auf
  • sortiert: Elemente tauchen beim Iterieren entsprechend ihre Kardinalität auf.

Frage: Die Klasse LinkedList taucht in der Tabelle zweimal auf. Wieso eigentlich?

Iteratoren

Neben dem spezifischen Zugriff auf diese abstrakten Datentypen bietet das  Java Collection Framework Iteratoren die es Erlauben, nacheinander alle Objekte einer Collection auszulesen. Hierzu dient die Schnittstelle Iterator. Iteratoren werden hier im Detail im Skript vorgestellt.

Beispiel

Im folgenden Beispiel werden Studenten in einer verzeigerten Liste verwaltet. Die Implementierung ist eine nicht generische Verwendung.

Klasse LinkedListDemo Klasse Student
package s2.collection;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
*
* @author s@scalingbits.com
*/
public class LinkedListIterDemo {

public static void main(String[] args) {
List<Student> ll = new LinkedList<>();
Student s;
s = new Student("Curie","Marie", 19,1);
ll.add(s);
s = new Student("Merian","Maria-Sybilla", 17,3);
ll.add(s);
s = new Student("Noether","Emmi", 16,1);
ll.add(s);
s = new Student("Herschel","Caroline", 15,2);
ll.add(s);

System.out.println("Element auf Index 1:" + ll.get(1));

Iterator<Student> iter = ll.iterator();
System.out.println("Inhalt der Liste:");
while (iter.hasNext()){
s = iter.next();
System.out.println("Student: " +s);
}

System.out.println("Inhalt der Liste:");
for (Student st : ll)
System.out.println("Student: " +st);
}
}

package s2.collection;
public class Student {
    int matrikelnr;
    String name;

public Student (String n, int nr) {
name = n;
matrikelnr = nr;
}

public String toString() {
return "("+matrikelnr+","+name+")";
}
}

 

 

Konsolenausgabe:

Element auf Index 1:(17,Merian Maria-Sybilla, 3)
Inhalt der Liste:
Student: (19,Curie Marie, 1)
Student: (17,Merian Maria-Sybilla, 3)
Student: (16,Noether Emmi, 1)
Student: (15,Herschel Caroline, 2)
Inhalt der Liste:
Student: (19,Curie Marie, 1)
Student: (17,Merian Maria-Sybilla, 3)
Student: (16,Noether Emmi, 1)
Student: (15,Herschel Caroline, 2)

In diesem Beispiel wurde eine gängige Technik angewendet:

  • Die Variable ll ist vom Schnittstellentyp List.
  • Die erzeugte Instanz ist vom Typ LinkedList. LinkedList ist eine spezielle Implementierung die man bei Bedarf gegen eine andere Implementierung austauschen kann ohne die anschließende Verwendung der Variable ll zu modifizieren. Dies würde hier durch die Auswahl der Klasse ArrayList geschehen. Man muss hierzu in der Methode main() nur eine Zeile ändern um das Laufzeitverhalten zu ändern:
List ll = new ArrayList();

 

Stefan Schneider Sat, 05/14/2011 - 14:40

Mikail (not verified)

Sun, 11/21/2021 - 04:48

Im Bereich wo die angebliche Konsolenausgabe abgebildet sein sollt, passt das Ergebnis also die Konsolenausgabe weder zu den Eingabe Parametern, noch zu der Klasse und damit Bedingung für die Parameterliste die für "new Student" gilt, da die Signaturen unterschiedlich sind.
In der Klasse Student haben wir eine Signatur Student(String, int)
In der LinkedListIterDemo Klasse haben wir aber eine Signatur von folgender Art Student(String, String, int, int) und in der Konsolenausgabe ist die Signatur Student(int, String, String, int).