CodeGym /Kurse /JAVA 25 SELF /Neue Kollektionen: SequencedCollection, SequencedSet, Seq...

Neue Kollektionen: SequencedCollection, SequencedSet, SequencedMap

JAVA 25 SELF
Level 34 , Lektion 4
Verfügbar

1. Das Ordnungsproblem in klassischen Kollektionen

In Java gab es schon immer Kollektionen, die die Reihenfolge der Elemente garantieren (zum Beispiel ArrayList, LinkedList, LinkedHashSet, LinkedHashMap), und solche, bei denen die Reihenfolge nicht garantiert ist (zum Beispiel HashSet, HashMap). Doch alle diese Kollektionen hatten einen gemeinsamen Nachteil: Obwohl einige von ihnen die Elemente in einer bestimmten Reihenfolge speichern, boten die Standard-Schnittstellen (List, Set, Map) keine universellen Methoden, um auf das erste und letzte Element zuzugreifen oder die Reihenfolge umzukehren.

Wenn Sie beispielsweise ein List<String> haben, können Sie das erste Element über list.get(0) erhalten, doch bei Set oder Map funktioniert dieser Trick nicht — Sie müssen Iteratoren verwenden oder zusätzlichen Code schreiben. Zugegeben, das ist nicht sehr praktisch und trägt nicht zur Lesbarkeit bei.

Das ist, als hätten Sie einen Schrank mit Schubladen, aber um die erste oder letzte Schublade herauszunehmen, müssten Sie jedes Mal alle Schubladen manuell nachzählen! Es wäre großartig, spezielle Griffe „erste“ und „letzte“ zu haben, oder?

Einführung von SequencedCollection und den zugehörigen Schnittstellen

In Java 21 sind neue Kollektion-Schnittstellen erschienen:

  • SequencedCollection<E>
  • SequencedSet<E>
  • SequencedMap<K, V>

Diese Schnittstellen erweitern die Standardkollektionen und führen einen einheitlichen Ansatz für den Umgang mit der Reihenfolge von Elementen ein. Nun kann man universellen Code für beliebige Kollektionen schreiben, bei denen die Reihenfolge wichtig ist, ohne über die konkrete Implementierung nachdenken zu müssen.

Was ist das?

  • SequencedCollection — das ist eine Kollektion, in der die Elemente eine bestimmte Reihenfolge haben, und Sie können leicht das erste, das letzte Element erhalten sowie die Reihenfolge umkehren.
  • SequencedSet — dasselbe, aber für Mengen (eindeutige Elemente).
  • SequencedMap — dasselbe, aber für Abbildungen (Schlüssel–Wert).

Welche Kollektionen implementieren sie jetzt?

In Java 21 implementieren die neuen Schnittstellen die folgenden Standardkollektionen:

  • ArrayList, LinkedListSequencedCollection
  • LinkedHashSet, TreeSetSequencedSet
  • LinkedHashMap, TreeMapSequencedMap

Das bedeutet, dass Sie diese neuen Möglichkeiten automatisch erhalten, wenn Sie diese Kollektionen bereits verwenden!

2. Zentrale Methoden von SequencedCollection, SequencedSet, SequencedMap

Methoden von SequencedCollection

E getFirst();      // Erstes Element abrufen
E getLast();       // Letztes Element abrufen
SequencedCollection<E> reversed(); // Kollektion in umgekehrter Reihenfolge erhalten

Methoden von SequencedSet

Dieselben Methoden wie bei SequencedCollection, plus alles, was Set bietet.

Methoden von SequencedMap

Map.Entry<K, V> firstEntry();    // Erster Eintrag (Schlüssel–Wert)
Map.Entry<K, V> lastEntry();     // Letzter Eintrag (Schlüssel–Wert)
SequencedMap<K, V> reversed();   // Map in umgekehrter Reihenfolge

3. Beispiele für die Verwendung der neuen Schnittstellen

Beispiel 1: Erstes und letztes Element abrufen

import java.util.*;

public class SequencedDemo {
    public static void main(String[] args) {
        SequencedCollection<String> sc = new ArrayList<>();
        sc.add("Java");
        sc.add("Python");
        sc.add("Kotlin");

        // Erstes und letztes Element abrufen
        String first = sc.getFirst(); // "Java"
        String last = sc.getLast();   // "Kotlin"

        System.out.println("Erstes: " + first);
        System.out.println("Letztes: " + last);
    }
}

Ausgabe:

Erstes: Java
Letztes: Kotlin

Beispiel 2: Kollektion umkehren

SequencedCollection<String> sc = new LinkedList<>();
sc.add("A");
sc.add("B");
sc.add("C");

SequencedCollection<String> reversed = sc.reversed();
System.out.println(reversed); // [C, B, A]

Beachten Sie: reversed() gibt eine Darstellung der Kollektion in umgekehrter Reihenfolge zurück. Wenn Sie die ursprüngliche Kollektion ändern, ändert sich auch die reversed-Darstellung!

Beispiel 3: Arbeiten mit SequencedSet

SequencedSet<Integer> set = new LinkedHashSet<>();
set.add(100);
set.add(200);
set.add(300);

System.out.println("Erstes Element: " + set.getFirst()); // 100
System.out.println("Letztes Element: " + set.getLast()); // 300

SequencedSet<Integer> reversedSet = set.reversed();
System.out.println(reversedSet); // [300, 200, 100]

Beispiel 4: Arbeiten mit SequencedMap

SequencedMap<String, Integer> map = new LinkedHashMap<>();
map.put("apple", 5);
map.put("banana", 3);
map.put("cherry", 7);

Map.Entry<String, Integer> first = map.firstEntry();
Map.Entry<String, Integer> last = map.lastEntry();

System.out.println("Erstes: " + first.getKey() + " = " + first.getValue()); // apple = 5
System.out.println("Letztes: " + last.getKey() + " = " + last.getValue()); // cherry = 7

SequencedMap<String, Integer> reversedMap = map.reversed();
System.out.println(reversedMap); // {cherry=7, banana=3, apple=5}

4. Was bedeutet das für Ihre Anwendung?

Angenommen, in Ihrer Lernanwendung speichern Sie eine Liste der Benutzer, die sich angemeldet haben, und möchten schnell den ersten und den letzten Benutzer ermitteln (z. B. für die Anzeige „wer sich zuerst angemeldet hat“ und „wer sich zuletzt angemeldet hat“). Früher musste man etwas schreiben wie:

List<String> users = new ArrayList<>();
// ... Benutzer hinzufügen
String first = users.get(0);
String last = users.get(users.size() - 1);

Wenn die Kollektion jedoch kein Liste ist, sondern zum Beispiel ein LinkedHashSet (bei dem die Elemente eindeutig sind und die Reihenfolge erhalten bleibt), funktioniert dieser Trick nicht:

Set<String> users = new LinkedHashSet<>();
// ... Benutzer hinzufügen
// Wie erhält man den ersten? Nur über einen Iterator:
String first = users.iterator().next();
// Und den letzten? Nur indem man alle Elemente durchläuft!

Jetzt ist alles einfacher und universeller:

SequencedSet<String> users = new LinkedHashSet<>();
// ... Benutzer hinzufügen
String first = users.getFirst();
String last = users.getLast();

Das reduziert nicht nur die Code-Menge, sondern macht ihn auch lesbarer und sicherer.

5. Schema der neuen Schnittstellen

classDiagram
    Collection <|-- SequencedCollection
    List <|-- SequencedCollection
    Set <|-- SequencedSet
    Map <|-- SequencedMap
    SequencedCollection <|-- SequencedSet
    SequencedSet <|-- LinkedHashSet
    SequencedSet <|-- TreeSet
    SequencedCollection <|-- ArrayList
    SequencedCollection <|-- LinkedList
    SequencedMap <|-- LinkedHashMap
    SequencedMap <|-- TreeMap

6. Nützliche Details

Praktische Vorteile von SequencedCollection

  • Einheitliche Schnittstelle für die Arbeit mit der Reihenfolge: Sie müssen sich nicht mehr merken, wo es get(0) gibt, wo ein Iterator nötig ist und wo man das erste Element überhaupt nicht erhalten kann.
  • Komfort bei der Arbeit mit Queues und Stacks: Einfaches Abrufen des ersten (head) und letzten (tail) Elements.
  • Sicherheit und Lesbarkeit: Weniger Fehler im Zusammenhang mit der falschen Verwendung von Kollektionen; der Code wird selbstdokumentierend.
  • Schnelles Umkehren der Kollektion: Die Methode reversed() ermöglicht es, die umgekehrte Reihenfolge ohne manuelle Eingriffe zu erhalten.
  • Einfachere Wartung und Erweiterung des Codes: Wenn Sie in Zukunft z. B. ArrayList durch LinkedHashSet ersetzen möchten, muss der Code, der SequencedCollection verwendet, nicht umgeschrieben werden.

Implementierungsdetails

  • Nicht alle Kollektionen implementieren SequencedCollection: Zum Beispiel HashSet und HashMap garantieren keine Reihenfolge und implementieren daher die neuen Schnittstellen nicht.
  • Methoden können Ausnahmen werfen: Wenn die Kollektion leer ist, führt der Aufruf von getFirst() oder getLast() zu einer NoSuchElementException. Vergessen Sie nicht zu prüfen, dass die Kollektion nicht leer ist!
  • reversed() — ist eine Darstellung (View), keine Kopie: Änderungen an der ursprünglichen Kollektion spiegeln sich in der umgekehrten Darstellung wider und umgekehrt.
  • Kompatibilität: Die neuen Schnittstellen sind erst ab Java 21 verfügbar. Wenn Sie eine ältere Java-Version verwenden, stehen Ihnen diese Möglichkeiten noch nicht zur Verfügung (aber das ist ein hervorragender Grund zu aktualisieren!).
  • Generics: Alle neuen Schnittstellen unterstützen Generics vollständig, sodass Sie mit beliebigen Datentypen arbeiten können.

7. Häufige Fehler im Umgang mit SequencedCollection

Fehler Nr. 1: Von Kollektionen Ordnung zu erwarten, die sie nicht garantieren. Wenn Sie versuchen, ein HashSet zu SequencedSet zu casten, erhalten Sie einen Kompilierfehler — HashSet hat keine Reihenfolge und implementiert diese Schnittstelle nicht.

Fehler Nr. 2: Leere Kollektionen ignorieren. Der Aufruf von getFirst() oder getLast() für eine leere Kollektion wirft eine Ausnahme. Stellen Sie vor dem Aufruf dieser Methoden sicher, dass die Kollektion nicht leer ist:

if (!sc.isEmpty()) {
    String first = sc.getFirst();
}

Fehler Nr. 3: Missverständnisse mit reversed(). Die Methode reversed() gibt eine Darstellung zurück, keine Kopie. Wenn Sie die reversed-Darstellung ändern, ändert sich auch die ursprüngliche Kollektion (und umgekehrt). Das kann zu unerwarteten Ergebnissen führen, wenn Sie ein solches Verhalten nicht erwarten.

Fehler Nr. 4: Verwendung der neuen Interfaces auf älteren Java-Versionen. Wenn Ihr Projekt mit einer Version unter Java 21 kompiliert wird, findet der Compiler diese Schnittstellen nicht. Prüfen Sie die Version des JDK in den Projekteinstellungen!

1
Aufgabe
JAVA 25 SELF, Level 34, Lektion 4
Gesperrt
Intelligenter Aufgaben-Dispatcher: Leereprüfung vor der Arbeit 🤖
Intelligenter Aufgaben-Dispatcher: Leereprüfung vor der Arbeit 🤖
1
Aufgabe
JAVA 25 SELF, Level 34, Lektion 4
Gesperrt
Ablaufschritte: Vorwärts- und Rückwärtssteuerung 🔄
Ablaufschritte: Vorwärts- und Rückwärtssteuerung 🔄
1
Umfrage/Quiz
Moderne Collections, Level 34, Lektion 4
Nicht verfügbar
Moderne Collections
Moderne Collections und Unveränderlichkeit
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION