Funkcionální programování v Javě
Proč to potřebuji?
Funkcionální programování v Javě (lambda výrazy, Stream API) umožňuje psát stručnější a expresivnější kód pro zpracování kolekcí. Je to moderní přístup, který výrazně zjednodušuje běžné operace jako filtrování, transformace a agregace dat.
Teorie
Funkcionální rozhraní = rozhraní s jednou abstraktní metodou, anotace @FunctionalInterface. Lze nahradit lambda výrazem.
Lambda výraz = anonymní funkce: (parametry) -> tělo.
High-order funkce = funkce, která přijímá nebo vrací jinou funkci. Stream API umožňuje řetězové zpracování kolekcí (map, filter, reduce).
Příklady
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
// === Funkcionální rozhraní ===
@FunctionalInterface
interface Prevod {
double preved(double hodnota);
}
// Lambda výraz
Prevod celsiusNaFahrenheit = c -> c * 9.0 / 5 + 32;
System.out.println(celsiusNaFahrenheit.preved(100)); // 212.0
// === Standardní funkcionální rozhraní ===
Predicate<String> jeDlouhy = s -> s.length() > 5;
Function<String, Integer> delka = String::length; // reference na metodu
Consumer<String> vypis = System.out::println;
Supplier<List<String>> novyList = ArrayList::new;
// === Stream API – map, filter, reduce ===
List<String> jmena = List.of("Jan", "Eva", "Kateřina", "Petr", "Alexandra");
// Filter + map + collect
List<String> dlouhaJmena = jmena.stream()
.filter(j -> j.length() > 3) // filter: ponechá jen splňující
.map(String::toUpperCase) // map: transformace každého prvku
.sorted() // seřazení
.collect(Collectors.toList()); // sbírání do seznamu
// ["ALEXANDRA", "KATEŘINA", "PETR"]
// Reduce – sčítání
List<Integer> cisla = List.of(1, 2, 3, 4, 5);
int soucet = cisla.stream()
.reduce(0, Integer::sum); // 15
// Statistiky
IntSummaryStatistics stats = cisla.stream()
.mapToInt(Integer::intValue)
.summaryStatistics();
System.out.println("Průměr: " + stats.getAverage()); // 3.0
System.out.println("Max: " + stats.getMax()); // 5
// Seskupení (groupingBy)
Map<Integer, List<String>> podleDelky = jmena.stream()
.collect(Collectors.groupingBy(String::length));
// {3=[Jan, Eva], 4=[Petr], 8=[Kateřina], 9=[Alexandra]}
// High-order funkce – metoda přijímající funkci
public static <T> List<T> filtruj(List<T> seznam, Predicate<T> podminka) {
return seznam.stream()
.filter(podminka)
.collect(Collectors.toList());
}
List<String> kratka = filtruj(jmena, j -> j.length() <= 3);
// ["Jan", "Eva"]
Shrnutí
Klíčové body
- Lambda:
(param) -> výraz, reference na metodu:Třída::metoda - Funkcionální rozhraní:
Predicate,Function,Consumer,Supplier - Stream:
filter(),map(),reduce(),collect() - Stream je lazy – operace se provedou až při terminální operaci (collect, reduce, forEach)