dh-Materialien
Java Tutorial
 

Listen

ArrayList<E> und Vector<E>   LinkedList<E>   Stack<E>   Die Klasse Collections   List-Komponenten

Das Interface List<E> aus dem Paket java.util ermöglicht es, Werte von Referenzvariablen in Listen zu speichern, mit anderen Worten: derartige Werte lassen sich sequentiell anordnen. Hierbei ist das Kürzel E ein Platzhalter für den jeweiligen Typ der Listenelemente. Der Zugriff auf die Elemente einer Liste erfolgt über einen ganzzahligen Index, beginnend bei 0.

Einige der durch List<E> bereitgestellten Methoden werden nachstehend beschrieben:

lst.add(int n, E obj)
fügt das Element obj vom Typ E an der n-ten Stelle in der Liste lst ein.
lst.add(E obj)
hängt das Element obj vom Typ E an die Liste lst an.
lst.clear()
löscht sämtliche Elemente der Liste lst.
lst.contains(Object obj)
liefert true zurück, falls obj zu lst gehört, andernfalls false.
lst.get(int n)
liefert das n-te Element der Liste lst zurück.
lst.indexOf(Object obj)
liefert die Stelle, an welcher sich obj zuerst befindet. Ist obj in der Liste lst nicht vorhanden, so wird −1 zurückgeliefert.
lst.remove(int n)
entfernt das n-te Element der Liste lst.
lst.remove(Object obj)
entfernt das Listenelement obj, und zwar dort, wo es in der Liste lst zuerst auftritt.
lst.set(int n, E obj)
ersetzt das n-te Element der Liste lst durch obj.
lst.size()
liefert die Anzahl der Elemente in der Liste lst zurück.

In den Klassen ArrayList<E>, LinkedList<E>, Vector<E> und Stack<E> (und anderen) sind neben den Methoden von List<E> auch die Methoden der Interfaces Iterable<E>, Collection<E>, Cloneable und Serializable implementiert.

Soll ein bestimmter Vorgang mit sämtlichen Elementen einer Liste durchgeführt werden, so kann dieses mit einer for-each-Schleife oder unter Verwendung der von Iterable bereitgestellten Methode forEach programmiert werden.

Die Implementierung von Cloneable stellt sicher, dass mittels der (von den eben erwähnten Klassen jeweils bereitgestellten) Methode clone Listen dupliziert werden können:

clone = lst.clone();
erstellt eine Kopie der Liste lst.

Das folgende Diagramm, ein Auszug aus der Vererbungshierarchie von Java, zeigt, wie die Klassen ArrayList<E>, LinkedList<E>, Vector<E> und Stack<E> miteinander zusammenhängen:

listdiagram

ArrayList<E> und Vector<E>

Eine Instanz der Klasse ArrayList<E> kann man sich anschaulich vorstellen als eine Kollektion aneinander gehefteter Behälter, die Werte von Referenzvariablen beinhalten können. Die Struktur einer Liste vom Typ ArrayList ähnelt also einem Array, allerdings gibt es wesentliche Unterschiede: Nach der Instanziierung bzw. Initialisierung eines Arrays ist seine Länge unveränderbar festgelegt; die Länge einer Liste ist dagegen während der Laufzeit eines Programms variabel. Die Elemente eines Arrays können auch von elementarem Typ sein, die Elemente einer Liste aber nicht. Hier müssen gegebenenfalls Wrapper-Klassen genutzt werden.

Jede Liste vom Typ ArrayList besitzt eine Kapazität, die festgelegt, wieviel Elemente diese Liste maximal umfassen kann. Der Aufruf des Konstruktors ArrayList() bzw. Vector() erzeugt jeweils eine leere Liste mit einer Kapazität von 10 Elementen; ArrayList(mincap) bzw. Vector(mincap) liefert jeweils eine leere Liste mit einer Kapazität von mincap Elementen, wobei mincap vom Typ int sein muss. Falls nötig, kann die Kapazität einer bereits vorhandenen Liste lst vergrößert werden:

lst.ensureCapacity(int mincap)

Das Einfügen eines neuen Elements in eine bestehende Liste vom Typ ArrayList funktioniert in den nachfolgend an einem Beispiel dargestellten Schritten. Hierbei repräsentieren die Ausdrücke 'a', 'b', ... die Referenzen auf Objekte vom Typ Character.

ArrayList add 

Die Verwendung der Klasse ArrayList<E> bietet sich vor allem dann an, wenn Suchvorgänge innerhalb einer vorhandenen Liste schnell vonstatten gehen sollen.

Die Klasse Vector<E> bietet die gleiche Funktionalität wie die Klasse ArrayList<E>. Der wesentliche Unterschied zwischen beiden Klassen besteht darin, dass Vector<E> synchronisiert ist und ArrayList<E> nicht, das heißt, dass auf eine Instanz vom Typ Vector nur jeweils ein Thread zur gleichen Zeit zugreifen darf.

LinkedList<E>

Eine Instanz der Klasse LinkedList<E> ist eine doppelt verlinkte Liste. Dies bedeutet, dass zu jedem Knoten einer solchen Liste drei Dinge gehören: das im Knoten gespeicherte Element vom Typ E, eine Referenz auf den Speicherort des nachfolgenden Knotens und eine Referenz auf den Speicherort des vorhergehenden Knotens. Beide Referenzen lassen sich anschaulich als Zeiger darstellen.

Das Einfügen eines neuen Elements in eine bestehende Liste vom Typ LinkedList funktioniert in den nachfolgend an einem Beispiel dargestellten Schritten. Hierbei repräsentieren die Ausdrücke 'c', 'd', ... die Referenzen auf Objekte vom Typ Character.

LinkedList add

Neben den oben aufgezählten Methoden gehören zu jeder Instanz lst der Klasse LinkedList<E> unter anderem noch folgende Methoden:

lst.addFirst(E obj)
fügt das Element obj vom Typ E am Anfang der Liste lst ein.
lst.addLast(E obj)
fügt das Element obj vom Typ E am Ende der Liste lst ein.
lst.peekFirst()
liefert das erste Element der Liste lst zurück. Ist die Liste lst leer, so wird null zurückgeliefert.
lst.peekLast()
liefert das letzte Element der Liste lst zurück.Ist die Liste lst leer, so wird null zurückgeliefert.
lst.pollFirst()
liefert das erste Element der Liste lst zurück und löscht dieses in der Liste. Ist die Liste lst leer, so wird null zurückgeliefert.
lst.pollLast()
liefert das letzte Element der Liste lst zurück und löscht dieses in der Liste. Ist die Liste lst leer, so wird null zurückgeliefert.

Die Verwendung der Klasse LinkedList<E> bietet sich vor allem dann an, wenn das Löschen, das Hinzufügen bzw. das Verschieben von Elementen innerhalb einer vorhandenen Liste schnell vonstatten gehen soll ( Javaprojekt SquarePuzzle).

Stack<E>

Die Instanzen der von Vector<E> abgeleiteten Klasse Stack<E> repräsentieren Last-In-First-Out-Stacks. Bei diesen, nach dem LIFO-Prinzip funktionierenden Stapeln, sind nur zwei Vorgänge zulässig: Entweder kann man das zuoberst auf dem Stapel liegende Element entfernen (sofern der Stapel nicht leer ist) oder es kann der Stapel um ein weiteres Element vergrößert werden. Demgemäß gehören zu einer Instanz stck der Klasse Stack<E> die folgenden Methoden:

stck.empty()
liefert true zurück, falls stck leer ist, andernfalls false.
stck.peek()
liefert das zuoberst liegende Element vom Stapel stck zurück, ohne es zu entfernen. Falls der Stapel leer ist, wird eine Fehlermeldung ausgegeben und das Programm bricht ab.
stck.pop()
liefert das zuoberst liegende Element vom Stapel stck zurück und entfernt es gleichzeitig vom Stapel. Falls der Stapel leer ist, wird eine Fehlermeldung ausgegeben und das Programm bricht ab.
stck.push(E obj)
legt ein neues Element oben auf den Stapel stck.
stck.search(Object obj)
liefert die Position von obj im Stapel als integer-Wert zurück. Das ganz oben liegende Element hat die Position 1, das darunter liegende Element die Position 2, und so fort. Ist das Objekt obj nicht im Stapel vorhanden, wird −1 zurückgeliefert.

Die Klasse Collections

Die Klasse Collections, ein Bestandteil des Java Collection Framework, beinhaltet Methoden für die Untersuchung, Sortierung, Veränderung, kurzum für die Verarbeitung von in Listen (lists), Mengen (sets), Stapeln (stacks), Warteschlangen (queues) oder Deques (double-ended-queues) gespeicherten Daten.

Die folgenden Programmzeilen liefern einen Überblick über einige dieser Methoden. Die Kommentarzeilen entsprechen dem, was in der Konsole angezeigt wird.

ArrayList<Integer> ilist = new ArrayList<>(List.of(74, 97));
ilist.addAll(List.of(118, 97));
System.out.println(ilist);
// [74, 97, 118, 97]

int f = Collections.frequency(ilist, 97);
System.out.println(f);
// 2

ArrayList<Character> clist = new ArrayList<>();
ilist.forEach(obj -> clist.add((char) obj.intValue()));
System.out.println(clist);
// [J, a, v, a]

Object m = Collections.max(clist);
System.out.println(m);
// v

Collections.sort(clist);
System.out.println(clist);
// [J, a, a, v]

Collections.reverse(clist);
System.out.println(clist);
// [v, a, a, J]

ArrayList<Integer> shlist;
shlist = new ArrayList<>(List.of(1, 2, 3, 4, 5, 6));
Collections.shuffle(shlist);
System.out.println(shlist);
// z.B. [4, 5, 1, 3, 2, 6]
Collections.shuffle(shlist);
System.out.println(shlist);
// z.B. [6, 1, 4, 2, 5, 3]

List-Komponenten

Die Instanzen der von java.awt.Component abgeleiteten Klasse java.awt.List sind scrollbare Listen von Texteinträgen, die beispielsweise in Textfeldern angezeigt werden können ( Javaprojekt SortingAlgorithms). Zu einer mit dem Konstruktor List() erzeugten Liste items gehören beispielweise folgende Methoden:

items.add(String item)
fügt der Liste items den neuen Texteintrag item hinzu.
items.getItem(int n)
liefert den Texteintrag an der n-ten Stelle der Liste items zurück.
items.getItemCount()
liefert die Anzahl der Texteinträge in der Liste items zurück.
items.getItems()
liefert sämtliche Texteinträge der Liste items als Array vom Typ String[] zurück.
items.remove(int n)
entfernt den Texteintrag an der n-ten Stelle der Liste items.
items.replaceItem(String newitem int n)
ersetzt den n-ten Texteintrag der Liste items durch newitem.
items.removeAll()
entfernt alle Texteinträge der Liste items.