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

Einführung in die funktionale Programmierung in Java



Lange Zeit wurde Java ausschließlich mit objektorientierter Programmierung (OOP) assoziiert. Mit der Veröffentlichung von Java 8 im Jahr 2014 machte die Sprache jedoch einen gewaltigen Schritt in Richtung des funktionalen Paradigmas. Lambda-Ausdrücke, funktionale Interfaces und die Stream API haben die Herangehensweise an das Schreiben von Code grundlegend verändert und ihn prägnanter, lesbarer und weniger fehleranfällig gemacht.



Funktionale Programmierung in Java ist kein Ersatz für OOP, sondern eine leistungsstarke Ergänzung. Sie ermöglicht es, deklarativen Code zu schreiben, bei dem Sie beschreiben, was getan werden soll, und nicht wie. In diesem Artikel werden wir die wichtigsten Konzepte behandeln, die Ihnen helfen, den funktionalen Stil in Java zu meistern, und praktische Beispiele zeigen.



1. Lambda-Ausdrücke und funktionale Interfaces



Die Grundlage der funktionalen Programmierung in Java sind Lambda-Ausdrücke – eine kompakte Möglichkeit, anonyme Funktionen zu implementieren. Syntaktisch besteht ein Lambda aus einer Parameterliste, einem Pfeil (->) und einem Rumpf:



(Parameter) -> { Rumpf }


Lambdas arbeiten immer paarweise mit funktionalen Interfaces. Ein funktionales Interface ist ein Interface, das genau eine abstrakte Methode enthält (z. B. Runnable, Comparator, Predicate).



Praktisches Beispiel: Ersetzen einer anonymen Klasse



Betrachten wir den Vergleich zwischen dem alten (OOP) und dem neuen (funktionalen) Ansatz:



// Alter Weg (anonyme Klasse)Runnable taskOld = new Runnable() {    @Override    public void run() {        System.out.println("Hallo aus der anonymen Klasse!");    }};

// Neuer Weg (Lambda)Runnable taskNew = () -> System.out.println("Hallo aus dem Lambda!");

// AusführungtaskNew.run();


Wie Sie sehen, hat das Lambda den Code von 6 Zeilen auf 1 reduziert, während die volle Funktionalität erhalten blieb.



Eingebaute funktionale Interfaces (Paket java.util.function)



Java bietet eine umfangreiche Sammlung eingebauter Interfaces. Hier sind die vier wichtigsten:



  • Predicate<T> – nimmt ein Objekt entgegen, gibt boolean zurück. Wird zum Filtern verwendet.
  • Function<T, R> – nimmt ein Objekt eines Typs entgegen, gibt ein Objekt eines anderen Typs zurück. Für Transformationen.
  • Consumer<T> – nimmt ein Objekt entgegen, gibt nichts zurück (void). Für Seiteneffekte (z. B. Ausgabe auf der Konsole).
  • Supplier<T> – nimmt nichts entgegen, gibt ein Objekt zurück. Für die verzögerte Generierung von Daten.


Beispiel mit Predicate:



import java.util.function.Predicate;

public class Main { public static void main(String[] args) { Predicate<Integer> isEven = n -> n % 2 == 0; System.out.println(isEven.test(10)); // true System.out.println(isEven.test(7)); // false }}


2. Stream API: Arbeiten mit Sammlungen im funktionalen Stil



Die Stream API ist das Juwel der funktionalen Programmierung in Java. Ein Stream ist eine Sequenz von Elementen, die sequentielle und parallele Operationen unterstützt. Der Hauptvorteil: Sie verändern die ursprünglichen Daten nicht, sondern erzeugen ein neues Ergebnis.



Die Stream API basiert auf drei Phasen:

  1. Erstellen eines Streams (aus einer Sammlung, einem Array oder einem Generator).
  2. Zwischenoperationen (Filtern, Sortieren, Transformieren). Geben einen neuen Stream zurück.
  3. Terminale Operation (Sammeln des Ergebnisses, Zählen, Suchen). Beendet die Arbeit des Streams.


Beispiel: Filtern und Transformieren einer Liste



Angenommen, wir haben eine Liste von Zeichenketten und möchten nur diejenigen, die länger als 3 Zeichen sind, in Großbuchstaben umwandeln und sortieren.



import java.u

Blogs

Buchempfehlungen