Java List: Ein umfassender Leitfaden für Anfänger und Entwickler

目次

1. Einführung

Was ist die Bedeutung von List in Java?

In der Java-Programmierung ist „List“ eine Datenstruktur, die sehr häufig vorkommt. Besonders in Situationen, in denen mehrere Werte zusammen verwaltet werden sollen, ist sie flexibler und einfacher zu benutzen als Arrays, was sie in vielen praktischen Szenarien sehr geschätzt macht.
„List“ ist ein Kerninterface im Java Collections Framework und bietet einen Mechanismus, verschiedene Situationen durch unterschiedliche Implementierungsklassen wie ArrayList und LinkedList zu handhaben. Die Möglichkeit, Operationen wie Hinzufügen, Löschen, Suchen und Aktualisieren von Daten intuitiv durchzuführen, ist einer der Gründe, warum List bevorzugt wird.

Zweck und Zielgruppe dieses Artikels

Dieser Artikel erklärt systematisch „Java List“ von den Grundlagen bis zu fortgeschrittenen Themen auf leicht verständliche Weise für Anfänger. Die Hauptzielgruppe ist wie folgt:

  • Personen, die gerade erst mit Java beginnen und unsicher sind, wie man List verwendet
  • Personen, die den Unterschied zwischen Array und List klar verstehen wollen
  • Personen, die Schwierigkeiten haben, zwischen ArrayList und LinkedList zu wählen
  • Personen, die die Grundlagen noch einmal überprüfen wollen, bevor sie List in der Praxis einsetzen

Bis zum Ende dieses Artikels soll es Ihnen gelingen, ein solides Verständnis der grundlegenden Konzepte, Implementierungsmethoden und spezifischen Operationen von List in Java zu erlangen, sodass Sie mit Vertrauen programmieren können.
Im nächsten Kapitel beginnen wir Schritt für Schritt mit der Erklärung des Grundteils, „Was ist List?“.

2. Was ist List?

Überblick und Eigenschaften von List

„List“ in Java ist ein Collection-Interface, das Elemente in einer geordneten Sequenz hält. Seine größten Merkmale sind, dass die Reihenfolge der Elementeinfügung erhalten bleibt und dass einzelne Elemente über einen Index (beginnend bei 0) zugänglich sind.
List ist Teil des Collections Framework und verfügt über die folgenden Eigenschaften:

  • Erlaubt doppelte Elemente
  • Ermöglicht das Abrufen, Aktualisieren und Löschen von Elementen durch Angabe eines Index
  • Kann die Anzahl der Elemente dynamisch erhöhen oder verringern (im Gegensatz zu Arrays ist es nicht festgelegt)

Dies ermöglicht flexible Datenmanipulation und wird sehr häufig in der Praxis eingesetzt.

Unterschied zu Arrays

In Java existieren Arrays (wie int[] oder String[]) ebenfalls als Mittel, mehrere Werte zu speichern, aber es gibt mehrere Unterschiede zu List.

Comparison ItemArrayList
Changing number of elementsNot possible (fixed-size)Possible (can increase/decrease dynamically)
Provided functionalityMinimal operations (indexed access, length retrieval)Rich methods (add, remove, contains, etc.)
TypeCan handle primitive typesObject types only (wrapper classes required)
Type safetyArrays checked at compile timeCan strictly specify type with Generics

Daher ist List eine flexiblere und funktionsreichere Sammlung, was sie in vielen Situationen praktischer macht als Arrays.

List-Interface und seine Implementierungsklassen

Bei der Verwendung von List in Java deklarieren Sie in der Regel eine Variable mit dem List-Interface und erstellen eine Instanz mit einer spezifischen Klasse (Implementierungsklasse). Repräsentative Implementierungsklassen sind wie folgt:

  • ArrayList Ähnliche Struktur wie ein Array, ermöglicht schnellen Zugriff. Stark bei der Suche nach Daten und zufälligem Zugriff.
  • LinkedList Implementiert mit einer doppelt verketteten Listenstruktur. Schnell beim Einfügen und Löschen, geeignet für Listen, bei denen Operationen häufig vorkommen.
  • Vector Ähnlich wie ArrayList, aber etwas schwerer, da es threadsicher ist. Wird heutzutage kaum noch verwendet.

In der Regel ist ArrayList die am häufigsten verwendete, es sei denn, es gibt einen besonderen Grund. Es ist sinnvoll, die passende auszuwählen, basierend auf dem später beschriebenen Leistungsvergleich, je nach Anwendungsfall.

3. Grundlegende Verwendung von List

Dieser Abschnitt erklärt die grundlegenden Operationen bei der Verwendung von List in Java Schritt für Schritt. Hier werden wir hauptsächlich ArrayList als Beispiel verwenden, um die repräsentativen Operationen von List vorzustellen.

Deklaration und Initialisierung von List

Zuerst schauen wir uns die grundlegende Deklaration und Initialisierung einer List mit ArrayList an.

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> fruits = new ArrayList<>();
    }
}

Es ist üblich, eine Variable mit dem List-Interface zu deklarieren und sie mit ArrayList zu instanziieren. Generics werden verwendet, um den zu speichernden Typ anzugeben (hier String).

Elemente hinzufügen (add)

Um Elemente zu einer Liste hinzuzufügen, verwenden Sie die Methode add().

fruits.add("apple");
fruits.add("banana");
fruits.add("orange");

Dies fügt drei Elemente der Liste in Reihenfolge hinzu. Die Liste bewahrt die Reihenfolge der Hinzufügung.

Elemente abrufen (get)

Um ein Element an einem bestimmten Index abzurufen, verwenden Sie get(int index).

System.out.println(fruits.get(0)); // "apple" will be displayed

Beachten Sie, dass Indizes bei 0 beginnen.

Elemente aktualisieren (set)

Um ein Element an einer bestimmten Position zu aktualisieren, verwenden Sie set(int index, E element).

fruits.set(1, "grape"); // The second element "banana" is replaced with "grape"

Elemente entfernen (remove)

Sie können Elemente auch anhand eines bestimmten Indexes oder des Elements selbst entfernen.

fruits.remove(0);           // Removes the first element
fruits.remove("orange");    // Removes "orange" (only the first match)

Listenlänge ermitteln (size)

Die aktuelle Anzahl der Elemente kann mit der Methode size() ermittelt werden.

System.out.println(fruits.size()); // Returns 2, etc.

Vorhandensein eines Elements prüfen (contains)

Um zu prüfen, ob ein bestimmtes Element in der Liste enthalten ist, verwenden Sie contains().

if (fruits.contains("grape")) {
    System.out.println("grape is present");
}

Zusammenfassung: Liste häufig verwendeter Grundoperationen

OperationMethod ExampleDescription
Additionadd("element")Adds to the end
Retrievalget(index)References an element
Updateset(index, new element)Changes the element at the specified position
Removalremove(index/element)Removes the specified element
Get Sizesize()Gets the number of elements
Check Existencecontains("element")Checks if a specific element exists

4. Beispiele für Listenoperationen

In diesem Kapitel stellen wir praktische Beispiele für die Verwendung von Java’s List vor. Es gibt viele Situationen, in denen Sie Elemente in einer Liste sequenziell verarbeiten möchten, und hier behandeln wir repräsentative Methoden mit for-Schleife, erweiterter for-Schleife und Stream API.

Iteration mit einer for-Schleife

Die grundlegendste Methode besteht darin, Elemente mithilfe eines Indexes innerhalb einer for-Schleife abzurufen.

List<String> fruits = new ArrayList<>();
fruits.add("apple");
fruits.add("banana");
fruits.add("orange");

for (int i = 0; i < fruits.size(); i++) {
    System.out.println(fruits.get(i));
}

Diese Methode ermöglicht fein abgestimmte Kontrolle mithilfe des Indexes. Zum Beispiel ist sie effektiv, wenn Sie nur Elemente an geraden Indizes verarbeiten möchten.

Iteration mit einer erweiterten for-Schleife (for-each)

Wenn Sie alle Elemente sequenziell verarbeiten möchten, ohne sich um den Index zu kümmern, ist die erweiterte for-Schleife praktisch.

for (String fruit : fruits) {
    System.out.println(fruit);
}

Die Syntax ist einfach und leicht lesbar, was sie zu einer der am häufigsten verwendeten Methoden macht. Das reicht für einfache Verarbeitung.

Iteration mit Lambda-Ausdrücken und Stream API

Seit Java 8 können Sie auch die Syntax mit Stream API und Lambda-Ausdrücken verwenden.

fruits.stream().forEach(fruit -> System.out.println(fruit));

Die Stärke dieser Notation besteht darin, dass mehrere Prozesse miteinander verkettet werden können. Zum Beispiel können Sie leicht filtern und dann Elemente basierend auf bestimmten Kriterien ausgeben.

fruits.stream()
      .filter(fruit -> fruit.contains("a"))
      .forEach(System.out::println);

In diesem Beispiel werden nur Früchte ausgegeben, die ein „a“ enthalten. Das ist besonders empfehlenswert für diejenigen, die sich an funktionalen Programmierstil gewöhnen wollen.

Die richtige Methode wählen

MethodAdvantagesSuitable Situations
Regular for loopAllows index controlProcessing that requires element numbers
Enhanced for loopSimple and easy to read syntaxSimple iteration processing
Stream APIStrong for conditional and chained processingWhen combining filtering, mapping, and reduction

5. Unterschiede und Verwendung von ArrayList und LinkedList

Die repräsentativen Klassen, die das Java-List-Interface implementieren, sind ArrayList und LinkedList. Beide können auf die gleiche Weise als List verwendet werden, unterscheiden sich jedoch in ihrer internen Struktur und Leistungscharakteristik, daher ist es wichtig, sie in den richtigen Situationen angemessen zu nutzen.

Eigenschaften und geeignete Anwendungsfälle von ArrayList

ArrayList verwendet intern ein dynamisches Array (vergrößerbares Array).

Hauptmerkmale:

  • Sehr schnell für Zufallszugriff (indexbasiert)
  • Hinzufügen von Elementen am Ende der Liste ist schnell (durchschnittlich O(1))
  • Einfügen und Löschen in der Mitte sind langsamer (O(n))

Geeignete Situationen:

  • Situationen, in denen das Suchen ( get() ) häufig ist
  • Situationen, in denen die Anzahl der Elemente im Voraus bis zu einem gewissen Grad vorhersehbar ist
  • Verarbeitung, bei der das Hinzufügen/Löschen von Elementen minimal ist und der Fokus auf dem Lesen liegt
    List<String> list = new ArrayList<>();
    

Merkmale und geeignete Anwendungsfälle von LinkedList

LinkedList wird mit einer doppelt verknüpften Listenstruktur implementiert.

Hauptmerkmale:

  • Schnell für das Hinzufügen und Löschen von Elementen (besonders am Anfang oder Ende)
  • Zufallszugriff ( get(index) ) ist langsam (O(n))
  • Speicherverbrauch ist etwas höher als bei ArrayList

Geeignete Situationen:

  • Situationen, in denen Elemente häufig eingefügt oder gelöscht werden (besonders am Anfang oder in der Mitte)
  • Wenn Sie es wie eine Queue oder einen Stack verwenden möchten
  • Wenn der Fokus auf der Iteration liegt und kein Indexzugriff benötigt wird
    List<String> list = new LinkedList<>();
    

Leistungsvergleich

Die folgende Tabelle zeigt die theoretische Zeitkomplexität (Big-O-Notation) für häufig verwendete Operationen.

OperationArrayListLinkedList
get(int index)O(1)O(n)
add(E e) (at the end)O(1)O(1)
add(int index, E e)O(n)O(n)
remove(int index)O(n)O(n)
IterationO(n)O(n)

* Die tatsächliche Verarbeitungszeit kann auch von der Datengröße, JVM-Optimierung usw. beeinflusst werden.

Punkte zur Unterscheidung der praktischen Nutzung

  • Wenn Sie Daten als Liste behandeln und per Index zugreifen, verwenden Sie ArrayList
  • Wenn Einfügen/Löschen am Anfang oder in der Mitte häufig ist, verwenden Sie LinkedList
  • Für leistungsempfindliche Verarbeitung immer benchmarken und überprüfen

6. Erweiterte Nutzung von List

Hier stellen wir erweiterte Techniken vor, um die Java-List noch bequemer zu nutzen. List kann verschiedene Operationen ausführen, nicht nur als einfache Datensammlung, sondern auch durch Sortieren, Mischen, Filtern, Transformation usw.

Sortieren einer Liste (Collections.sort)

Mit Collections.sort() können Sie die Elemente in einer Liste in aufsteigender Reihenfolge sortieren. Die Elemente müssen das Comparable-Interface implementieren.

import java.util.*;

List<String> fruits = new ArrayList<>();
fruits.add("banana");
fruits.add("apple");
fruits.add("orange");

Collections.sort(fruits);

System.out.println(fruits); // [apple, banana, orange]

Sortieren in einer benutzerdefinierten Reihenfolge (mit Comparator)

fruits.sort(Comparator.reverseOrder()); // Sorts in descending order

Mischen einer Liste (Collections.shuffle)

Um die Elemente zufällig umzuordnen, können Sie Collections.shuffle() verwenden.

Collections.shuffle(fruits);
System.out.println(fruits); // [banana, orange, apple] (example)

Das ist nützlich, wenn Sie ein Kartendeck für ein Spiel oder eine zufällige Anzeigereihenfolge möchten.

Filtern mit Stream API (filter)

Mit Stream ab Java 8 können Sie Code knapp schreiben, um nur Elemente zu extrahieren, die einer Bedingung entsprechen.

List<String> filtered = fruits.stream()
    .filter(fruit -> fruit.contains("a"))
    .collect(Collectors.toList());

System.out.println(filtered); // [apple, banana, orange] (depending on original content and filter)

Transformation mit Stream API (map)

Um Elemente in ein anderes Format zu transformieren, verwenden Sie map().

List<Integer> lengths = fruits.stream()
    .map(String::length)
    .collect(Collectors.toList());

System.out.println(lengths); // Lengths of each fruit name [5, 6, 6] etc.

map() ist ein mächtiges Tool für Datenformatkonvertierung und Vorverarbeitung.

Zusammenfassung erweiterter Operationen

OperationUsage ExampleMain Use Cases
SortCollections.sort(list)Sort in ascending order
ShuffleCollections.shuffle(list)Randomize the order of elements
Filterstream().filter(...).collect()Extract only elements that match a condition
Transformstream().map(...).collect()Transform the type or value of elements

7. Häufige Fehler und ihre Lösungen

Beim Arbeiten mit Listen in Java stoßen Anfänger oft über „Ausnahmen (Fehler)“ ins Stocken. Hier erklären wir speziell repräsentative Fehler, die häufig auftreten, ihre Ursachen und wie man sie löst.

IndexOutOfBoundsException

Ursache:

Tritt auf, wenn versucht wird, auf einen nicht existierenden Index zuzugreifen.

List<String> list = new ArrayList<>();
list.add("apple");

System.out.println(list.get(1)); // Error: Index 1 out of bounds

Lösung:

Überprüfen Sie die Größe, bevor Sie darauf zugreifen, oder steuern Sie den Zugriff mit bedingter Verzweigung, um sicherzustellen, dass der Index gültig ist.

if (list.size() > 1) {
    System.out.println(list.get(1));
}

NullPointerException

Ursache:

Tritt auf, wenn eine Methode auf einer List oder einem List-Element aufgerufen wird, das null ist.

List<String> list = null;
list.add("apple"); // NullPointerException occurs

Lösung:

Überprüfen Sie im Voraus, ob die Variable nicht null ist, oder nutzen Sie Optional, usw.

if (list != null) {
    list.add("apple");
}

Achten Sie außerdem darauf, nicht zu vergessen, zu initialisieren:

List<String> list = new ArrayList<>(); // Correct initialization

ConcurrentModificationException

Ursache:

Tritt auf, wenn die List direkt während der Iteration mit einer for-each-Schleife oder einem Iterator geändert wird.

for (String fruit : list) {
    if (fruit.equals("banana")) {
        list.remove(fruit); // ConcurrentModificationException
    }
}

Lösung:

Verwenden Sie einen Iterator, um Elemente sicher zu entfernen, oder nutzen Sie Methoden wie removeIf().

Iterator<String> it = list.iterator();
while (it.hasNext()) {
    if (it.next().equals("banana")) {
        it.remove(); // Safe removal
    }
}

Oder, prägnanter ab Java 8:

list.removeIf(fruit -> fruit.equals("banana"));

Weitere Punkte, die zu beachten sind

  • Überprüfen, ob die List nicht null ist
  • Es ist sehr üblich, eine Variable zu deklarieren, sie aber nicht zu verwenden. Initialisierung ist entscheidend.
  • Verstehen, dass Indizes bei 0 beginnen
  • Anfänger denken oft fälschlicherweise, dass „das erste Element den Index 1 hat“.

Zusammenfassung der Fehlerabwehrmaßnahmen

Error NamePrimary CauseExample Solutions
IndexOutOfBoundsExceptionAccessing a non-existent indexCheck length with size()
NullPointerExceptionList or element is nullDon’t forget initialization, perform null checks
ConcurrentModificationExceptionDirectly modifying the List during iterationOperate with Iterator or utilize removeIf()

8. Fazit

Grundlagen der Java List überprüfen

In diesem Artikel haben wir die Grundlagen bis hin zu fortgeschrittenen Aspekten der List in Java Schritt für Schritt erklärt. Die List wird besonders häufig unter den Java-Sammlungen verwendet und ist ein wichtiges Werkzeug für die flexible Handhabung von Daten. Zunächst haben wir, nachdem wir verstanden haben, was eine List ist, die folgenden Punkte gelernt:

  • Die List ist eine sortierte Sammlung, die Duplikate zulässt und Indexoperationen unterstützt
  • Es gibt repräsentative Implementierungsklassen wie ArrayList und LinkedList, die jeweils unterschiedliche Eigenschaften und Anwendungsfälle haben
  • Die Beherrschung grundlegender Operationen (add, get, update, remove, search) ermöglicht eine flexible Datenmanipulation
  • Iterative Verarbeitung, die für die Situation geeignet ist, wie z. B. for-Schleifen, erweiterte for-Schleifen und die Stream-API
  • Unterstützt fortgeschrittene Operationen wie Sortieren, Filtern und Transformation
  • Das Verständnis häufiger Fehler, ihrer Ursachen und Lösungen hilft, Probleme zu verhindern

Unterscheidung zwischen ArrayList und LinkedList

Die Wahl der List-Implementierung ist wichtig und sollte auf dem Inhalt der Verarbeitung und der Datenmenge basieren. Die folgenden Kriterien können als Leitfaden dienen:

  • ArrayList : Häufiger zufälliger Zugriff, hauptsächlich Lesen
  • LinkedList : Häufige Einfüge/Entferne, die Reihenfolge des Zugriffs ist wichtig

Ausblick auf zukünftiges Lernen

Die List ist lediglich der „Einstiegspunkt“ zu den Java-Sammlungen. Um komplexere Datenstrukturen und Hilfsprogramme zu handhaben, wird empfohlen, Ihr Verständnis der folgenden Klassen und Funktionen zu vertiefen:

  • Set und Map : Verwaltung eindeutiger Elemente, Schlüssel-Wert-Paar-Struktur
  • Collections Utility-Klasse : Sortieren, Min/Max finden, usw.
  • Verwendung der Stream-API : Einführung in funktionale Programmierung
  • Verständnis von Generics : Typsichere Sammlung-Operationen

Die Beherrschung der Grundlagen der List wird Ihre gesamte Java-Programmierung deutlich einfacher zu handhaben.

Häufig gestellte Fragen (FAQ)

Wir haben Punkte zusammengestellt, zu denen Anfänger häufig Fragen bezüglich der Java-List haben. Wir haben Inhalte ausgewählt, die in der Praxis häufig auftreten.

Q1. Was ist der Unterschied zwischen Java’s List und Array?

A. Ein Array hat eine feste Anzahl von Elementen und seine Größe muss bei der Deklaration bestimmt werden. Im Gegensatz dazu hat eine List eine variable Größe, die flexible Hinzufügung und Löschung von Elementen ermöglicht. Darüber hinaus bietet List viele praktische Methoden (add, remove, contains usw.) und ist in Bezug auf Lesbarkeit und Wartbarkeit überlegen.

Q2. Welche sollte ich verwenden, ArrayList oder LinkedList?

A. ArrayList ist hauptsächlich geeignet, wenn häufig Zufallszugriff (Abruf per Index) erfolgt. LinkedList ist geeignet, wenn Elemente häufig eingefügt und gelöscht werden. Im Zweifelsfall ist es generell empfehlenswert, mit ArrayList zu beginnen.

Q3. Kann ich primitive Typen (wie int oder double) in einer List speichern?

A. Nicht direkt. Da Java’s List nur Objekttypen verarbeitet, müssen Sie für primitive Typen wie int die entsprechenden Wrapper-Klassen (Integer, Double usw.) verwenden.

List<Integer> numbers = new ArrayList<>();
numbers.add(10); // Auto-boxed and stored as Integer type

Q4. Wie kann ich die Elemente in einer List sortieren?

A. Sie können die Elemente in aufsteigender Reihenfolge mit Collections.sort(list) sortieren. Wenn Sie die Elemente in einer benutzerdefinierten Reihenfolge sortieren möchten, können Sie einen Comparator für flexible Sortierung angeben.

Q5. Was soll ich tun, wenn ich Elemente ohne Duplikate verwalten möchte?

A. List ist eine Sammlung, die Duplikate zulässt. Wenn Sie Duplikate vermeiden möchten, sollten Sie ein Set (z. B. HashSet) verwenden. Beachten Sie jedoch, dass die Reihenfolge nicht garantiert ist. Wenn Sie Duplikate entfernen möchten, während die Struktur als List erhalten bleibt, ist die folgende Stream-Verarbeitung ebenfalls möglich:

List<String> distinctList = list.stream()
    .distinct()
    .collect(Collectors.toList());

Q6. Was soll ich tun, wenn ich alle Elemente aus einer List löschen möchte?

A. Sie können alle Elemente einer List mit der Methode clear() entfernen.

list.clear();

Q7. Was sind die am häufigsten verwendeten Operationen in einer List?

A. Die am häufigsten verwendeten Operationen in der Praxis sind add (Hinzufügen), get (Abruf), remove (Löschen) und size (Größenabfrage). Das Beherrschen dieser Operationen deckt die meisten grundlegenden Verarbeitungen ab.