08.03 Die List-Schnittstelle
Aus dem letzten Kapitel kennen Sie bereits die Collection
-Schnittstelle. Das Interface java.util.List
(nachfolgend als List
oder Liste bezeichnet, und nicht zu verwechseln mit der Klasse java.awt.List
) erbt von Collection
und spezifiziert java.util.Collection
somit genauer.
Allgemeines zu Listen
Ebenso wie die Collection
-Schnittstelle, enthält auch eine List
mehrere Objekte eines bestimmten Datentyps. Wird dieser Datentyp nicht über Generics definiert, sind auch unterschiedliche Datentypen in einer Liste möglich. Dieser Zustand sollte allerdings nach Möglichkeit vermieden werden. Die Art, wie die Elemente in einer List
„liegen“, ist genauer spezifiziert als in der Collection
:
- Eine Liste ist sortiert. Das bedeutet, dass jedes Objekt in einer Liste über einen Index (wie bei einem Array) angesprochen werden kann. Dies funktioniert bspw. mit der Methode
list.get(index);
. Durch die Sortierung ist auch sichergestellt, dass die Liste zur Laufzeit nicht einfach die Position, also den Index, der Objekte verändern darf/kann. - Doppelte Einträge sind erlaubt. So können mehrere identische Objekte (
o1.equals(o2);
) in eine Liste eingefügt werden. Falls die Liste das Hinzufügen vonnull
gestattet, können typischerweise auch mehrerenull
-Objekte hinzugefügt werden. Natürlich ist es nicht auszuschließen, dass eineList
das Einfügen von doppelten Einträgen durch Werfen einerException
unterbindet. - Ebenso wie Arrays, fangen Listen bei 0 an zu zählen. Der erste Index ist also 0, der Zweite 1, der Dritte 2, …
- Zusätzlich zum
Iterator
imCollection
-Interface, stellt eineList
auch einenListIterator
zur Verfügung. EinListIterator
erlaubt es Objekte hinzuzufügen und zu ersetzen, und stellt eine Funktionalität bereit, um bidirektional auf ihn zuzugreifen.
Ansonsten zählt natürlich alles, was für eine Collection
auch zählt. Somit ist eine List
am ehesten mit einem dynamischen Array zu vergleichen.
Methoden einer List (zusätzlich zu den Methoden von java.util.Collection
)
- add(int index, E element) – fügt das Objekt an der spezifischen Stelle in der Liste ein. Das Element, das sich zuvor an dieser Stelle befand, und alle nachfolgenden Elemente, werden um jeweils eine Stelle weiter nach rechts verschoben (aus 3 wird 4, aus 4 wird 5, aus 5 wird 6, …)
- addAll(int index, Collection<? extends E> c) – fügt die
Collection c
an der spezifizierten Stelle in die Liste ein. Das Element an dieser Stelle und alle darauffolgenden Elemente, werden um die Größe vonc
nach rechts verschoben. - get(int index) – gibt das Objekt an Stelle
index
zurück. - indexOf(Object o) – gibt die Stelle zurück, an der sich das gegebene Objekt befindet. Falls sich das Objekt nicht in der Liste befindet, gibt diese Methode -1 zurück.
- lastIndexOf(Object o) – so wie
indexOf(Object o)
, nur, dass die Stelle des letzten Objekts, das gleicho
ist, zurückgegeben wird. - listIterator() – gibt einen
ListIterator
für diese Liste zurück. - listIterator(int index) – gibt einen
ListIterator
für diese Liste zurück, der an der Stelleindex
beginnt. - remove(int index) – entfernt das Objekt an der Stelle
index
von derList
. - set(int index, E element) – überschreibt das Objekt an der Stelle
index
mit dem Objektelement
. - subList(int fromIndex, int toIndex) – gibt eine Liste mit den Elementen in der Liste
fromIndex
(inklusiv) bistoIndex
(exklusiv) zurück.
Verwendung
Java bietet bereits mehrere Implementierungen einer List
. Die Wichtigsten werden im Kapitel 08.06 Implementierungen von List vorgestellt. An dieser Stelle folgt noch ein kleines Beispiel mit einer java.util.ArrayList
, die Sie im Java Blog Buch bereits mehrmals verwendet haben.
List<String> myList = new ArrayList<String>(); myList.add("String eins"); myList.add("String zwei"); myList.add("String drei"); for (String str : myList) { System.out.println(str); } List<String> myList2 = new ArrayList<String>(); myList2.addAll(myList); myList2.remove("String eins"); myList2.remove(1); for (String str : myList2) { System.out.println(str); } System.out.println(myList.get(0));
Hallo,
ich habe gerade leidvoll erfahren, dass eine ArrayList nur die Referenzen bzgl. der mit der add()-Methode hinzugefügten Objekte „beinhaltet“. Nun würde ich gerne in einer Schleife int[]-Arrays als Elemente einer ArrayList bestimmen und dieser ArrayList hinzufügen. Leider werden in den „Update-Berechnungen“ innerhalb der Schleife über die einzelne Referenz auf das int[]-Array natürlich alle „Objekte der ArrayList“ geändert. Wie kann man das verhindern?
Viele Grüße
Daniel
Hallo Daniel,
Sie könnten bspw. eine Wrapper-Klasse verwenden, die lediglich ein Attribut – nämlich ein
int
-Array – enthält. Dieses fügen Sie dann anstelle des eigentlichenint
-Arrays derArrayList
hinzu, und aktualisieren dieses auch entsprechend.Falls noch etwas unklar ist, oder ich Sie falsch verstanden haben sollte, können Sie gerne noch einmal nachfragen.
Grüße
Stefan
Mir ist eine Möglichkeit bei List aufgefallen, die man verwenden kann. Nur bin ich mir nicht sicher, ab man das so machen kann:
Nämlich erstelle ich kein Objekt einer Klasse, die List implementiert, sondern direkt eines des Interfaces List selber; nur ohne Initialisierung. Später greife ich dann darauf zu, ohne das Objekt vorher initialisiert zu haben.
Meine Frage: Ist das eine gute Lösung, oder sollte ich auf eine Klasse wie ArrayList ausweichen und mit der initialisieren?
Code:
private List icons;
Und in einer Methode dann:
icons.add(new Icon(usw….
Danke im Voraus und Grüsse meinerseits
Cyrill
Hallo Cyrill,
ohne die Liste irgendwo irgendwie zu initialisieren (bzw. initialisieren zu lassen) bekommt man beim Hinzufügen eine NullPointerException. Ich bezweifle also, dass Ihre „Möglichkeit“ funktioniert. Ich lasse mich mit einem kleinen, ausführbaren Programm gerne eines besseren belehren 😉 .
Grüße
Stefan