Alle Tabs der Lerneinheit (Erklärung · Interaktiv verstehen · Praxis-Übung · Klausur-Quiz) als durchgehender Text. Ideal zum Wiederholen vor der Klausur, und für Suchmaschinen wie Google, Bing und KI-Suche (ChatGPT, Perplexity).
Diese Lerneinheit wurde für typische Bachelor-Klausuren konzipiert. So prüfen wir · Fehler entdeckt? Melde ihn uns oder markiere die fragliche Stelle direkt im Text oben.
Alle Tabs der Lerneinheit (Erklärung · Interaktiv verstehen · Praxis-Übung · Klausur-Quiz) als durchgehender Text. Ideal zum Wiederholen vor der Klausur, und für Suchmaschinen wie Google, Bing und KI-Suche (ChatGPT, Perplexity).
Du brauchst eine Datenstruktur, die nicht-statisch ist? Java's Collections-Framework liefert dir 3 große Familien: List (geordnete Reihenfolge, Duplikate ok), Set (keine Duplikate), Map (Key-Value-Zuordnung). Sie sind das Brot-und-Butter-Werkzeug in jedem Java-Programm.
Klausur-Pflicht in 10/13 WInf-Prog-1-Klausuren: "Wann List, wann Set, wann Map?" — und die typischen Operationen.
Klausur-Tipp: Bei Klausurfragen zur Datenstruktur-Wahl frag dich: (1) Ist die Reihenfolge wichtig? → List. (2) Sind Duplikate ok? Wenn nein → Set. (3) Brauche ich Lookup über einen Schlüssel? → Map. In 90% aller Fälle reicht diese Entscheidungslogik.
Anmelden, um den Fortschritt zu speichern.
Nächster Schritt
Aktives Abrufen festigt Wissen schneller als nochmal lesen.
Du brauchst eine Datenstruktur, die nicht-statisch ist? Java's Collections-Framework liefert dir 3 große Familien: List (geordnete Reihenfolge, Duplikate ok), Set (keine Duplikate), Map (Key-Value-Zuordnung). Sie sind das Brot-und-Butter-Werkzeug in jedem Java-Programm.
Klausur-Pflicht in 10/13 WInf-Prog-1-Klausuren: "Wann List, wann Set, wann Map?" — und die typischen Operationen.
Collections sind Container für Objekte mit klaren Regeln: List behält die Einfüge-Reihenfolge bei und erlaubt Duplikate, Set verhindert Duplikate, Map verbindet Schlüssel mit Werten.
| Familie | Reihenfolge | Duplikate | Lookup-Schlüssel | Wichtigster Vertreter |
|---|---|---|---|---|
| List<E> | ja (Index 0, 1, 2 ...) | ja | Index (int) | ArrayList<E> |
| Set<E> | normalerweise nein | nein | – (keine direkte Suche) | HashSet<E> |
| Map<K, V> | – | Werte ja, Keys nein | Key (K) | HashMap<K, V> |
Verwende List wenn: du Items in einer bestimmten Reihenfolge speichern willst und Duplikate erlaubt sind.
import java.util.ArrayList;
import java.util.List;
List<String> namen = new ArrayList<>();
namen.add("Anna");
namen.add("Ben");
namen.add("Anna"); // Duplikat ist ok
System.out.println(namen); // [Anna, Ben, Anna]
System.out.println(namen.size()); // 3
System.out.println(namen.get(1)); // Ben
namen.remove(0);
System.out.println(namen); // [Ben, Anna]
Wichtigste Operationen:
add(e) — hinten anfügenadd(i, e) — an Index i einfügenget(i) — Element holenset(i, e) — Element ersetzenremove(i) — Element löschensize() — Anzahlcontains(e) — enthält? (O(n)!)indexOf(e) — erster IndexVerwende Set wenn: du nur prüfen willst, ob etwas vorkommt, und Duplikate egal sind (sollen weg).
import java.util.HashSet;
import java.util.Set;
Set<String> tags = new HashSet<>();
tags.add("java");
tags.add("oop");
tags.add("java"); // Duplikat wird ignoriert!
System.out.println(tags.size()); // 2
System.out.println(tags.contains("oop")); // true (sehr schnell, O(1))
Wichtigste Operationen:
add(e) — hinzufügen (true wenn neu)contains(e) — enthält? (O(1) bei HashSet)remove(e) — entfernensize()get(i)! Sets haben keine Indizes.HashSet vs. TreeSet: HashSet ist unsortiert, sehr schnell. TreeSet ist sortiert (alphabetisch / numerisch), aber langsamer (O(log n)).
Verwende Map wenn: du Werte unter einem Schlüssel ablegen willst — "Telefonbuch"-Pattern.
import java.util.HashMap;
import java.util.Map;
Map<String, Integer> noten = new HashMap<>();
noten.put("Anna", 1);
noten.put("Ben", 3);
noten.put("Anna", 2); // ersetzt Annas alte Note!
System.out.println(noten.get("Anna")); // 2
System.out.println(noten.containsKey("Ben")); // true
System.out.println(noten.size()); // 2
Wichtigste Operationen:
put(k, v) — Wert unter Key speichern (überschreibt)get(k) — Wert holen (null wenn nicht da)containsKey(k) — Key vorhanden?remove(k) — Eintrag löschenkeySet() — alle Keys als Setvalues() — alle Werte als CollectionentrySet() — alle Key-Value-Paare// List
for (String name : namen) {
System.out.println(name);
}
// Set
for (String tag : tags) {
System.out.println(tag);
}
// Map
for (Map.Entry<String, Integer> eintrag : noten.entrySet()) {
System.out.println(eintrag.getKey() + " = " + eintrag.getValue());
}
Klausur-Frage: "Was passiert wenn du während des for-each-Loops Elemente entfernst?" → ConcurrentModificationException. Lösung: Iterator explizit nutzen oder removeIf(...).
| Interface | Implementierung | Charakteristik |
|---|---|---|
| List | ArrayList | dynamisches Array, schneller Index-Zugriff (O(1)) |
| List | LinkedList | doppelt-verkettete Liste, schnelles Insert/Remove an Enden |
| Set | HashSet | Hash-basiert, schnell (O(1)), unsortiert |
| Set | TreeSet | rot-schwarz-Baum, sortiert, O(log n) |
| Set | LinkedHashSet | wie HashSet aber merkt Einfüge-Reihenfolge |
| Map | HashMap | Hash-basiert, schnell (O(1)), unsortiert |
Daumenregel: Wenn unsicher → ArrayList, HashSet, HashMap. Die sind 90% aller Fälle die richtige Wahl.
| Problem | Datenstruktur | Begründung |
|---|---|---|
| Bestellte Items im Warenkorb | List | Reihenfolge zählt, Duplikate (2x dasselbe Buch) ok |
| Eindeutige Tags eines Posts | Set | Duplikate sinnlos, schnelle "enthält?"-Abfrage |
| User-ID → User-Objekt | Map | Schlüssel-Lookup |
| Eindeutige Email-Adressen | Set | Email kann nur 1x vorkommen |
| Top-10-Bestseller | List | Reihenfolge IST die Information |
| Wörter alphabetisch | TreeSet | sortiert + duplikatfrei |
1. List = geordnet + Duplikate. Set = duplikatfrei. Map = Key→Value. Ende.
2. ArrayList ist Default-List. HashMap ist Default-Map. HashSet ist Default-Set. Spezialisierte Implementierungen erst wenn du einen Grund hast.
3. Hash-Implementierungen sind O(1) für add/contains/get. Tree-Implementierungen O(log n). Listen O(n) für contains.
4. null als Wert/Key: HashMap und HashSet erlauben null (einmal). TreeMap und TreeSet werfen NullPointerException, weil sie sortieren müssen.
5. equals und hashCode müssen konsistent sein wenn du eigene Klassen in Sets/Maps speicherst. Sonst tauchen Objekte mehrfach auf oder werden nicht gefunden.
1. Set mit Index zugreifen. set.get(0) gibt's nicht. Wenn du Index brauchst → List.
2. map.get(key) ohne Null-Check. Wenn Key nicht da → null zurück. Ein NullPointerException bei der nächsten Operation ist garantiert. Lösung: containsKey vorher oder getOrDefault.
3. Collections.sort(set) versuchen. Set ist nicht sortiert (ausser TreeSet). sort funktioniert nur auf List. Wenn du eine sortierte Reihenfolge willst: new ArrayList<>(set) und dann sortieren.
4. Eigene Objekte in HashSet/HashMap ohne equals/hashCode override. Standard-equals vergleicht Referenzen, nicht Inhalt. Zwei Student-Objekte mit gleichem Namen sind dann "verschieden". Lösung: equals und hashCode überschreiben.
5. ConcurrentModificationException beim Iterieren + Entfernen. Niemals in einem for-each-Loop collection.remove(...) aufrufen. Lösung: removeIf(predicate) oder expliziter Iterator mit it.remove().
3 identische Operationen, ausgeführt auf List, Set, Map gleichzeitig. Beobachte die Unterschiede.
Wähle eine Operation aus und sieh, was bei jeder Datenstruktur passiert. So merkst du dir Reihenfolge / Duplikate / Lookup-Verhalten ohne auswendig zu lernen.
Interaktive Visualisierung
Interaktive Komponente: probiere sie im Topic-Player oben aus.
Klausur-Tipp: Bei Klausurfragen zur Datenstruktur-Wahl frag dich: (1) Ist die Reihenfolge wichtig? → List. (2) Sind Duplikate ok? Wenn nein → Set. (3) Brauche ich Lookup über einen Schlüssel? → Map. In 90% aller Fälle reicht diese Entscheidungslogik.
6 Aufgaben zur Wahl der richtigen Datenstruktur und ihren Operationen.
Klausurfragen mit Lösungen (6)
Antwort: HashSet<String>
Erklärung: Set — eindeutige Werte ohne Reihenfolge-Bedeutung. HashSet ist die Default-Wahl: schnelles add/contains, automatisch duplikatfrei. ArrayList würde Duplikate erlauben, HashMap braucht Keys, Stack wäre LIFO-Reihenfolge.
Antwort: HashMap<Integer, Student>
Erklärung: Map<Integer, Student> — die Matrikelnummer ist der Schlüssel, das Student-Objekt der Wert. studenten.get(12345) liefert in O(1) den passenden Studenten. ArrayList wäre O(n) Suche, Set ohne Index sinnlos.
Antwort: Falsch
Erklärung: FALSCH. HashSet hat KEINE definierte Reihenfolge — Hashcode-basierte Anordnung intern, oft anders als Einfüge-Reihenfolge. Wenn du Einfüge-Reihenfolge brauchst: LinkedHashSet. Wenn sortiert: TreeSet.
Typ: Wahr/Falsch
Antwort: Falsch
Erklärung: FALSCH. put mit existierendem Key überschreibt den alten Wert. Map.size() = 1, map.get("Anna") = 2. Keys in Maps sind eindeutig — wenn du mehrere Werte unter einem Key willst: Map<String, List<Integer>>.
Typ: Wahr/Falsch
Richtige Antworten: ArrayList erlaubt Duplikate; Set hat keine get(i)-Methode; HashMap erlaubt null als Key; List.add(e) hängt am Ende an
Erklärung: Richtig: ArrayList erlaubt Duplikate, Set hat keinen Index, HashMap erlaubt 1x null als Key, List.add hängt hinten an. Falsch: HashSet ist duplikatfrei (Definition!), TreeSet ist sortiert (nicht unsortiert).
Typ: Multi-Select
Zuordnungen:
Erklärung: Standard-Entscheidungs-Vokabular. Reihenfolge → List, Eindeutigkeit → Set, Lookup → Map, sortiert + eindeutig → TreeSet.
Typ: Zuordnung
Klausurfragen mit Lösungen (6)
Antwort: O(1) amortisiert
Erklärung: HashSet nutzt Hash-Tabelle: contains ist O(1) amortisiert (schlimmster Fall O(n) bei Hash-Kollisionen). TreeSet wäre O(log n), ArrayList wäre O(n) wegen linearer Suche.
Antwort: ConcurrentModificationException zur Laufzeit
Erklärung: ConcurrentModificationException. Der Iterator merkt, dass die Liste sich strukturell geändert hat. Lösung: explizit Iterator nutzen mit it.remove() oder list.removeIf(predicate).
Antwort: Wahr
Erklärung: RICHTIG. Tree-Implementierungen müssen vergleichen (sortieren). null lässt sich nicht mit anderen Werten vergleichen → NullPointerException beim Einfügen. HashMap und HashSet erlauben dagegen 1x null.
Typ: Wahr/Falsch
Antwort: 1, wenn equals() und hashCode() überschrieben sind, sonst 2
Erklärung: Standard-equals vergleicht REFERENZEN, nicht Inhalt. Zwei verschiedene Student-Instanzen sind technisch verschieden → beide landen im Set. Damit HashSet sie als gleich erkennt, MUSST du equals() UND hashCode() überschreiben (Vertrag: gleich → gleicher hashCode).
Lösungen pro Lücke:
Erklärung: Kern-Vokabular der 3 Collections. List = Reihenfolge + Duplikate. Set = duplikatfrei. Map = Key→Value. HashMap = Default für Maps.
Typ: Lückentext
Richtige Reihenfolge:
Erklärung: Iterator-Pattern für sicheres Entfernen. it.remove() ist erlaubt — list.remove() im for-each wäre ConcurrentModificationException. Alternative: list.removeIf(predicate) in einer Zeile.
Typ: Reihenfolge
| Map | TreeMap | rot-schwarz-Baum, nach Keys sortiert |
| Map | LinkedHashMap | wie HashMap aber Einfüge-Reihenfolge |