Funktionale Programmierung in Java: Fortgeschrittene Techniken und 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: Fortgeschrittenes Niveau



Funktionale Programmierung (FP) ist ein Paradigma, bei dem Berechnungen als Auswertung mathematischer Funktionen betrachtet werden, die Zustandsänderungen und veränderliche Daten vermeiden. Java, obwohl eine objektorientierte Sprache, hat mit der Veröffentlichung von Java 8 leistungsstarke Werkzeuge für FP erhalten: Lambda-Ausdrücke, das Stream API und funktionale Interfaces. Auf fortgeschrittenem Niveau ermöglichen diese Funktionen das Schreiben von prägnanterem, sichererem und ausdrucksstärkerem Code, insbesondere bei der Arbeit mit Collections, asynchronen Operationen und der Fehlerbehandlung.



In diesem Artikel werden wir fortgeschrittene Techniken der funktionalen Programmierung in Java betrachten: Funktionskomposition, Monaden (Optional und CompletableFuture), das Stream API mit paralleler Verarbeitung und Currying.



1. Funktionskomposition und funktionale Interfaces



In Java sind funktionale Interfaces Interfaces mit einer einzigen abstrakten Methode (SAM). Die am häufigsten verwendeten sind: Function<T, R>, Predicate<T>, Consumer<T> und Supplier<T>. Die fortgeschrittene Nutzung umfasst die Komposition von Funktionen mit den Methoden andThen() und compose().



Beispiel: Transformationskette



import java.util.function.Function;

public class FunctionComposition { public static void main(String[] args) { // Funktion: String -> seine Länge Function<String, Integer> lengthFunction = String::length; // Funktion: Zahl -> ihr Quadrat Function<Integer, Integer> squareFunction = x -> x * x;

// Komposition: String -> Länge -> Quadrat der Länge Function<String, Integer> composedFunction = lengthFunction.andThen(squareFunction);

String text = "Hello, Java!"; int result = composedFunction.apply(text); // 12 * 12 = 144 System.out.println("Ergebnis: " + result); // 144 }}


Die Methode andThen() wendet zuerst die erste Funktion an, dann die zweite. compose() macht das Gegenteil: Es wendet zuerst die übergebene Funktion an, dann die erste. Dies ermöglicht den Aufbau flexibler und wiederverwendbarer Transformationsketten.



Praktisches Beispiel: Filtern und Transformieren einer Liste



import java.util.List;import java.util.function.Function;import java.util.function.Predicate;import java.util.stream.Collectors;

public class PredicateAndFunction { public static void main(String[] args) { List<String> names = List.of("Alice", "Bob", "Charlie", "David", "Eve");

Predicate<String> startsWithA = s -> s.startsWith("A"); Function<String, String> toUpperCase = String::toUpperCase;

List<String> result = names.stream() .filter(startsWithA) .map(toUpperCase) .collect(Collectors.toList());

System.out.println(result); // [ALICE] }}


2. Monaden in Java: Optional und CompletableFuture



Eine Monade ist ein Muster, das einen Wert kapselt und Operationen zu seiner Transformation bereitstellt, ohne ihn explizit auspacken zu müssen. In Java werden Monaden durch Optional (zur Behandlung von null) und CompletableFuture (für asynchrone Operationen) implementiert.



Optional als Monade

Die Methoden map(), flatMap() und filter() ermöglichen die verkettete Arbeit mit der möglichen Abwesenheit eines Wertes.



import java.util.Optional;

public class OptionalMonad { public static void main(String[] args) { // Erstellen eines Optional mit einem nicht-leeren Wert Optional<String> optional = Optional.of("Hello");

// Transformationskette String result = optional .filter(s -> s.length() > 3) // filter .m

Blogs

Buchempfehlungen