Funktionale Programmierung in Java: Von Lambdas bis zur Stream API

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Funktionale Programmierung in Java: Von Lambdas bis zur Stream API



Funktionale Programmierung (FP) ist ein Paradigma, bei dem Berechnungen als Auswertung mathematischer Funktionen dargestellt werden, wobei Zustandsänderungen und Datenmutationen vermieden werden. Lange Zeit blieb Java eine streng objektorientierte Sprache, aber mit der Veröffentlichung von Java 8 (2014) machte sie einen großen Schritt in Richtung FP, indem sie Lambda-Ausdrücke, funktionale Interfaces und die Stream API hinzufügte. Heute sind diese Werkzeuge unverzichtbar für das Schreiben von prägnantem, lesbarem und nebenläufig-sicherem Code.



In diesem Artikel werden wir die Schlüsselkonzepte der funktionalen Programmierung in Java behandeln: von den Grundlagen der Lambdas bis zur fortgeschrittenen Sammlungsverarbeitung mit der Stream API. Das Material richtet sich an Entwickler, die bereits mit der grundlegenden Java-Syntax vertraut sind, aber moderne Ansätze erlernen möchten.



1. Lambda-Ausdrücke und funktionale Interfaces



Ein Lambda-Ausdruck ist eine anonyme Funktion (Methode ohne Namen), die als Argument übergeben oder in einer Variable gespeichert werden kann. In Java implementiert ein Lambda ein funktionales Interface – ein Interface mit genau einer abstrakten Methode (SAM – Single Abstract Method).



Syntax:

(Parameter) -> { Rumpf }


Beispiel: Anstatt eine anonyme Klasse für einen Comparator zu erstellen:

// Alter Weg (Java 7)Comparator<String> comparator = new Comparator<String>() {    @Override    public int compare(String s1, String s2) {        return s1.length() - s2.length();    }};

// Neuer Weg (Java 8+)Comparator<String> comparatorLambda = (s1, s2) -> s1.length() - s2.length();


Wichtige funktionale Interfaces in Java (Paket java.util.function):

  • Predicate<T> – prüft eine Bedingung (Methode test).
  • Function<T, R> – wandelt ein Objekt vom Typ T in R um (Methode apply).
  • Consumer<T> – führt eine Aktion an einem Objekt aus (Methode accept).
  • Supplier<T> – liefert ein Objekt ohne Eingabeparameter (Methode get).


Beispiel mit Predicate:

Predicate<Integer> isEven = n -> n % 2 == 0;System.out.println(isEven.test(4)); // trueSystem.out.println(isEven.test(5)); // false


Methodenreferenzen (Method References) sind eine Kurzschreibweise für Lambdas, wenn der Rumpf aus einem einzigen Methodenaufruf besteht:

// Lambdalist.forEach(item -> System.out.println(item));// Methodenreferenzlist.forEach(System.out::println);


2. Stream API: Grundlegende Operationen



Die Stream API ist ein leistungsstarkes Werkzeug zur Verarbeitung von Datensequenzen (Sammlungen, Arrays, Dateien) in einem deklarativen Stil. Ein Stream speichert keine Daten, sondern beschreibt nur eine Pipeline von Operationen. Die Daten werden nicht verändert – jeder Schritt erzeugt einen neuen Stream.



Erstellen eines Streams:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");Stream<String> stream = names.stream(); // sequentiellStream<String> parallelStream = names.parallelStream(); // parallel


Intermediäre Operationen (geben einen neuen Stream zurück):

  • filter(Predicate) – wählt Elemente nach einer Bedingung aus.
  • map(Function) – transformiert jedes Element.
  • sorted() / sorted(Comparator) – Sortierung.
  • distinct() – entfernt Duplikate.
  • limit(n) – begrenzt die Anzahl der Elemente.


Terminale Operationen (beenden den Stream, geben ein Ergebnis zurück):

  • collect(Collectors.toList()) – sammelt in eine Sammlung.
  • forEach(Con

Blogs

Buchempfehlungen