Ce face Function
Function<T, R> este tipul unei funcții cu un parametru: primește un T și returnează un R. Este o interfață funcțională (are o singură metodă abstractă, apply), deci o poți crea dintr-o expresie lambda: Function<String, Integer> lungime = s -> s.length(); sau dintr-o referință de metodă: String::length.
apply(valoare) rulează funcția și returnează rezultatul. Așa poți păstra o funcție într-o variabilă, o poți da ca parametru unei metode sau o poți pune într-un map.
Stream.map primește exact o Function. Pentru tipuri primitive există variante fără împachetare: IntFunction, ToIntFunction, IntUnaryOperator etc.
Parametri
| Parametru | Descriere |
|---|---|
t |
Pentru apply: valoarea de intrare. |
Ce returnează
apply returnează rezultatul funcției, de tip R.
Exemple
Exemplul 1: Funcții în variabile
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
Function<String, Integer> lungime = String::length;
Function<Double, Double> cuTva = pret -> pret * 1.21;
System.out.println(lungime.apply("Timișoara"));
System.out.println(cuTva.apply(100.0));
}
}
Rezultat
9
121.0
Exemplul 2: O metodă care primește o funcție
Metoda transforma nu știe ce face funcția; primește regula ca parametru.
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public class Main {
static <T, R> List<R> transforma(List<T> lista, Function<T, R> f) {
List<R> rezultat = new ArrayList<>();
for (T element : lista) {
rezultat.add(f.apply(element));
}
return rezultat;
}
public static void main(String[] args) {
List<String> orase = List.of("Iași", "Cluj", "Brăila");
System.out.println(transforma(orase, String::toUpperCase));
System.out.println(transforma(orase, o -> o + " (" + o.length() + ")"));
}
}
Rezultat
[IAȘI, CLUJ, BRĂILA]
[Iași (4), Cluj (4), Brăila (6)]
Exemplul 3: Un map de operații
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
Map<String, Function<Integer, Integer>> operatii = new TreeMap<>();
operatii.put("dublu", x -> x * 2);
operatii.put("pătrat", x -> x * x);
operatii.put("minus", x -> -x);
operatii.forEach((nume, f) -> System.out.println(nume + "(7) = " + f.apply(7)));
}
}
Rezultat
dublu(7) = 14
minus(7) = -7
pătrat(7) = 49
Greșeli frecvente
- Folosești
Function<Integer, Integer>pentru calcule multe cu numere. Fiecare apel împachetează valori;IntUnaryOperatorevită asta. - Încerci să apelezi funcția ca
f(5). În Java scriif.apply(5). - Ai nevoie de doi parametri.
Functionare unul; foloseșteBiFunction.
Comenzi înrudite
Function.andThen: Leagă două funcții una după alta: f.andThen(g) rulează întâi f, apoi g; f.compose(g) rulează întâi g, apoi f.Function.identity: Funcția care returnează exact valoarea primită; utilă în toMap și groupingBy când elementul însuși e cheia sau valoarea.BiFunction: O funcție cu doi parametri (de tipuri T și U) care returnează un R; o apelezi cu apply(a, b).UnaryOperator: O Function în care intrarea și ieșirea au același tip (T → T); folosită de List.replaceAll și Stream.iterate.Stream.map: Transformă fiecare element al stream-ului în altă valoare, eventual de alt tip.