🌊 1. Die Anatomie einer Java Stream-Pipeline
Anstelle imperativer for-Schleifen mit temporären Variablen beschreiben Streams was getan werden soll, nicht wie es im Detail geschieht.
└── (Intermediäre Ops: Lazy) ──┘ └── (Terminal: Eager) ──┘
// Modernes Idiom:
List<String> topPerformers = employees.stream()
.filter(e -> e.salary() > 80000)
.map(Employee::name)
.sorted()
.collect(Collectors.toList());
📊 2. Collectors & Null-Safety mit Optional
Mit Collectors.groupingBy aggregierst du Datensätze in Millisekunden nach Kategorien oder Abteilungen:
Gruppiert Datensätze in eine Map<Key, List<T>>.
Kombination mit averagingDouble oder counting().
Sichere Null-Vermeidung mit map() und orElse().
Stell dir ein Postfließband vor: Die Pakete gleiten am Scanner vorbei (filter entfernt zu schwere Pakete), werden automatisch umetikettiert (map) und fallen über Weichen direkt in die passenden Rollcontainer (Collectors.groupingBy) – ohne dass ein Mitarbeiter jedes Paket einzeln anfassen muss!
📑 3. Cheat-Sheet: Streams API & Optional Operationen
| Operation | Typ | Beschreibung & Verhalten |
|---|---|---|
.filter(Predicate<T>) |
Intermediär | Behält nur Elemente, die das Prädikat erfüllen |
.map(Function<T, R>) |
Intermediär | Transformiert jedes Element in einen neuen Typ |
.flatMap(Function<T, Stream<R>>) |
Intermediär | Ebnet verschachtelte Streams/Listen in einen flachen Stream ein |
.collect(Collectors.groupingBy(...)) |
Terminal | Aggregiert Daten in eine Map<K, V> |
Optional.map().orElse(...) |
Null-Safety | Transformiert sicheren Wert oder liefert Standardwert |
🧠 Diagnostischer Selbst-Check
Überprüfe dein Verständnis von Sprach-Features, Speicherverwaltung und Enterprise-Architektur, bevor du den Code in der Web-IDE schreibst.
🎯 Aufgaben & Checkliste in Aufgabe.java
Nutze wann immer möglich Methodenreferenzen wie Employee::salary statt Lambdas wie e -> e.salary(). Das verbessert die Lesbarkeit und vermeidet anonyme Klasseninstanziierungen.