Java List: Ein umfassender Leitfaden für Einsteiger 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 Sie mehrere Werte zusammen verwalten möchten, ist sie flexibler und einfacher zu verwenden als Arrays, was sie in vielen praktischen Szenarien hoch geschätzt macht.

„List“ ist eine Kernoberfläche im Java Collections Framework und bietet einen Mechanismus, um verschiedene Situationen durch unterschiedliche Implementierungsklassen wie ArrayList und LinkedList zu handhaben. Die Fähigkeit, Operationen wie das 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 wird „Java List“ systematisch von den Grundlagen bis zu fortgeschrittenen Themen auf eine für Anfänger leicht verständliche Weise erklären. Die Hauptzielgruppe ist wie folgt:

  • Diejenigen, die gerade anfangen, Java zu lernen und unsicher sind, wie man List verwendet
  • Diejenigen, die den Unterschied zwischen Array und List klar verstehen möchten
  • Diejenigen, die mit der Wahl zwischen ArrayList und LinkedList kämpfen
  • Diejenigen, die die Grundlagen überprüfen möchten, bevor sie List in der Praxis verwenden

Bis zum Ende dieses Artikels ist unser Ziel, dass Sie ein solides Verständnis der grundlegenden Konzepte, Implementierungsmethoden und spezifischen Operationen von List in Java erlangen, sodass Sie selbstbewusst programmieren können.

Ab dem nächsten Kapitel werden wir mit der Erklärung des grundlegenden Teils „Was ist List?“ Schritt für Schritt beginnen.

2. Was ist List?

Überblick und Merkmale von List

„List“ in Java ist eine Sammlungsoberfläche, die Elemente in einer geordneten Sequenz speichert. Ihre größten Merkmale sind, dass die Reihenfolge des Hinzufügens von Elementen erhalten bleibt und dass einzelne Elemente mit einem Index (beginnend bei 0) zugänglich sind.

List wird als Teil des Collections Frameworks bereitgestellt und hat die folgenden Merkmale:

  • Erlaubt doppelte Elemente
  • Kann Elemente durch Angabe eines Indexes abrufen, aktualisieren und löschen
  • Kann die Anzahl der Elemente dynamisch erhöhen oder verringern (im Gegensatz zu Arrays ist sie nicht fest groß)

Dies ermöglicht flexible Datenmanipulation und wird in der praktischen Arbeit sehr häufig verwendet.

Unterschied zu Array

In Java existieren Arrays (wie int[] oder String[]) ebenfalls als Mittel, um 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, die in vielen Situationen praktischer als Arrays ist.

List-Oberfläche und ihre Implementierungsklassen

Beim Verwenden von List in Java deklarieren Sie im Allgemeinen eine Variable mit der List-Oberfläche 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 Zufallszugriff.
  • LinkedList Implementiert mit einer doppelt verknüpften Listenstruktur. Schnell beim Einfügen und Löschen, geeignet für Listen, bei denen Operationen häufig sind.
  • Vector Ähnlich wie ArrayList, aber etwas schwerer, da es thread-sicher ist. Wird heutzutage nicht viel verwendet.

Im Allgemeinen wird ArrayList am häufigsten verwendet, es sei denn, es gibt einen speziellen Grund. Es ist gut, die geeignete basierend auf dem später beschriebenen Leistungsvergleich je nach Anwendungsfall zu wählen.

3. Grundlegende Verwendung von List

Dieser Abschnitt erklärt die grundlegenden Operationen beim Verwenden 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 gängige Praxis, 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 der Liste nacheinander drei Elemente hinzu. Die Liste erhält die Reihenfolge der Hinzufügungen.

Elemente abrufen (get)

Um ein Element an einem angegebenen Index zu erhalten, 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 über einen bestimmten Index oder das Element selbst entfernen.

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

Listengröße 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 List‑Operationen

In diesem Kapitel stellen wir praktische Beispieloperationen mit Java‑Listen vor. Es gibt viele Situationen, in denen Sie Elemente 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 über einen Index 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 feinkörnige Kontrolle über den Index. 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 zu lesen, was sie zu einer der am häufigsten verwendeten Methoden macht. Sie reicht für einfache Verarbeitungen aus.

Iteration mit Lambda‑Ausdrücken und Stream API

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

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

Der Vorteil dieser Notation liegt darin, dass mehrere Prozesse hintereinander geschaltet werden können. Zum Beispiel können Sie leicht filtern und anschließend 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. Dies ist besonders empfehlenswert für diejenigen, die sich an das funktionale Programmieren gewöhnen möchten.

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 dieselbe Weise als Liste verwendet werden, weisen jedoch Unterschiede in ihrer internen Struktur und ihren Leistungseigenschaften auf, sodass es wichtig ist, sie in den jeweiligen Situationen angemessen einzusetzen.

Eigenschaften und geeignete Anwendungsfälle von ArrayList

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

Hauptmerkmale:

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

Geeignete Situationen:

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

Eigenschaften und geeignete Anwendungsfälle von LinkedList

LinkedList ist mit einer doppelt verketteten Listenstruktur implementiert.

Hauptmerkmale:

  • Schnell beim Hinzufügen und Löschen von Elementen (insbesondere am Anfang oder Ende)
  • Zufälliger Zugriff (get(index)) ist langsam (O(n))
  • Der Speicherverbrauch ist etwas höher als bei ArrayList

Geeignete Situationen:

  • Situationen, in denen Elemente häufig eingefügt oder gelöscht werden (insbesondere am Anfang oder in der Mitte)
  • Wenn Sie es wie eine Warteschlange (Queue) oder einen Stapel (Stack) verwenden möchten
  • Wenn der Fokus auf Iteration liegt und ein Indexzugriff nicht 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 Datenmenge, JVM-Optimierung usw. beeinflusst werden.

Punkte zur praktischen Unterscheidung der Nutzung

  • Wenn Sie Daten als Liste behandeln und per Index darauf zugreifen, verwenden Sie ArrayList
  • Wenn Einfügen/Löschen am Anfang oder in der Mitte häufig vorkommt, verwenden Sie LinkedList
  • Bei leistungssensitiver Verarbeitung immer benchmarken und verifizieren

6. Fortgeschrittene Nutzung von List

Hier stellen wir fortgeschrittene Techniken vor, um Java’s List noch komfortabler zu nutzen. List kann verschiedene Operationen nicht nur als einfache Datensammlung, sondern auch durch Sortieren, Mischen, Filtern, Transformieren usw. ausführen.

Sortieren einer Liste (Collections.sort)

Mit Collections.sort() können Sie die Elemente 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 neu anzuordnen, 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 benötigen.

Filtern mit der Stream-API (filter)

Mit Stream ab Java 8 können Sie kompakt Code 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 der 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 leistungsfähiges Werkzeug für Datenformatkonvertierung und Vorverarbeitung.

Zusammenfassung fortgeschrittener 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 deren Lösungen

Beim Arbeiten mit Listen in Java stoßen Anfänger häufig auf „Ausnahmen (Fehler)“. 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 bedingten Verzweigungen, 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 Listenelement aufgerufen wird, das null ist.

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

Lösung:

Stellen Sie vorher sicher, dass die Variable nicht null ist, oder verwenden Sie Optional usw.

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

Achten Sie auch darauf, das Initialisieren nicht zu vergessen:

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

ConcurrentModificationException

Ursache:

Tritt auf, wenn die Liste direkt geändert wird, während sie mit einer for-each‑Schleife oder einem Iterator durchlaufen 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, kürzer ab Java 8:

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

Weitere zu beachtende Punkte

  • Überprüfen, dass die Liste nicht null ist
  • Es ist sehr häufig, eine Variable zu deklarieren, aber nicht zu verwenden. Initialisierung ist essenziell.
  • Verstehen, dass Indizes bei 0 beginnen
  • Anfänger denken oft fälschlich, dass „das erste Element Index 1 ist“.

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

Überblick über die Grundlagen von Java List

In diesem Artikel haben wir die Grundlagen bis zu fortgeschrittenen Aspekten von List in Java Schritt für Schritt erklärt. List wird besonders häufig unter den Java‑Collections verwendet und ist ein wichtiges Werkzeug für die flexible Handhabung von Daten.

Zuerst, nachdem wir verstanden haben, was List ist, haben wir die folgenden Punkte gelernt:

  • List ist eine geordnete Sammlung, die Duplikate zulässt und Indexoperationen unterstützt
  • Es gibt repräsentative Implementierungsklassen wie ArrayList und LinkedList, jede mit unterschiedlichen Merkmalen und Anwendungsfällen
  • Das Beherrschen grundlegender Operationen (add, get, update, remove, search) ermöglicht flexible Datenmanipulation
  • Iterative Verarbeitung passend zur Situation, wie for‑Schleifen, erweiterte for‑Schleifen und Stream‑API
  • Unterstützt erweiterte Operationen wie Sortieren, Filtern und Transformieren
  • Das Verstehen häufiger Fehler, ihrer Ursachen und Lösungen hilft, Probleme zu vermeiden

Unterscheidung zwischen der Verwendung von ArrayList und LinkedList

Die Wahl der zu verwendenden 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äufiges Einfügen/Löschen, Zugriffsreihenfolge ist wichtig

Auf zukünftiges Lernen ausgerichtet

List ist nur der „Einstiegspunkt“ in die Java‑Collections. Um fortgeschrittenere Datenstrukturen und Hilfsmittel zu handhaben, wird empfohlen, Ihr Verständnis der folgenden Klassen und Features zu vertiefen:

  • Set und Map: Verwaltung eindeutiger Elemente, Schlüssel‑Wert‑Struktur
  • Collections Hilfsklasse: Sortieren, Minimum/Maximum finden usw.
  • Verwendung der Stream‑API: Einführung funktionaler Programmierung
  • Verstehen von Generics: Typensichere Collection‑Operationen

Das Beherrschen der Grundlagen von List wird Ihr gesamtes Java‑Programmieren deutlich einfacher zu handhaben machen.

Häufig gestellte Fragen (FAQ)

Wir haben Punkte zusammengestellt, zu denen Anfänger häufig Fragen zu Java’s List haben. Wir haben Inhalte ausgewählt, die in der Praxis häufig vorkommen.

Q1. Was ist der Unterschied zwischen Javas List und Array?

A. Ein Array hat eine feste Anzahl von Elementen und seine Größe muss bei der Deklaration festgelegt werden. Andererseits hat eine List eine variable Größe, die ein flexibles Hinzufügen und Entfernen von Elementen ermöglicht. Darüber hinaus bietet List viele bequeme Methoden (add, remove, contains usw.) und ist in Bezug auf Lesbarkeit und Wartbarkeit überlegen.

Q2. Welche sollte ich verwenden, ArrayList oder LinkedList?

A. ArrayList eignet sich hauptsächlich, wenn es häufig zufälligen Zugriff (Abruf per Index) gibt. LinkedList eignet sich, wenn Elementeinfügungen und -löschungen häufig vorkommen. Bei Unsicherheit wird empfohlen, mit ArrayList zu beginnen.

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

A. Nicht direkt. Da Javas List nur Objekttypen handhabt, müssen für primitive Typen wie int die entsprechenden Wrapper-Klassen (Integer, Double usw.) verwendet werden.

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 in aufsteigender Reihenfolge mit Collections.sort(list) sortieren. Wenn Sie in einer benutzerdefinierten Reihenfolge sortieren möchten, können Sie einen Comparator für flexible Sortierung angeben.

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

A. List ist eine Sammlung, die Duplikate erlaubt. Wenn Sie Duplikate vermeiden möchten, sollten Sie eine Set (z. B. HashSet) in Betracht ziehen. Beachten Sie jedoch, dass die Reihenfolge nicht garantiert ist. Wenn Sie Duplikate entfernen möchten, während es eine List bleibt, ist die folgende Stream-Verarbeitung ebenfalls möglich:

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

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

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

list.clear();

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

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