Function.identity în Java

Funcția care returnează exact valoarea primită; utilă în toMap și groupingBy când elementul însuși e cheia sau valoarea.

Sintaxă
static <T> Function<T, T> identity()

Ce face Function.identity

Function.identity() este echivalentul lui x -> x. Pare inutilă, dar multe metode cer o funcție, iar uneori vrei chiar elementul neschimbat.

Cazuri tipice: groupingBy(Function.identity(), counting()) numără de câte ori apare fiecare element; toMap(Function.identity(), String::length) face un map de la cuvânt la lungimea lui. Este și un punct de pornire bun pentru un lanț construit cu andThen.

Ce returnează

O Function<T, T> care returnează argumentul neschimbat.

Exemple

Exemplul 1: Cuvânt → lungime și frecvența literelor

import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<String> cuvinte = List.of("mere", "pere", "caise");
        Map<String, Integer> lungimi = cuvinte.stream()
                .collect(Collectors.toMap(Function.identity(), String::length, (a, b) -> a, TreeMap::new));
        System.out.println(lungimi);

        Map<String, Long> litere = "banana".chars().mapToObj(Character::toString)
                .collect(Collectors.groupingBy(Function.identity(), TreeMap::new, Collectors.counting()));
        System.out.println(litere);
    }
}

Rezultat

{caise=5, mere=4, pere=4}
{a=3, b=1, n=2}

Exemplul 2: Punct de pornire pentru un lanț de operații

Pornim de la funcția identitate și adăugăm pași doar dacă sunt ceruți.

import java.util.function.Function;

public class Main {
    static Function<String, String> construieste(boolean faraSpatii, boolean majuscule) {
        Function<String, String> f = Function.identity();
        if (faraSpatii) {
            f = f.andThen(String::strip);
        }
        if (majuscule) {
            f = f.andThen(String::toUpperCase);
        }
        return f;
    }

    public static void main(String[] args) {
        String text = "  Iași  ";
        System.out.println("[" + construieste(false, false).apply(text) + "]");
        System.out.println("[" + construieste(true, false).apply(text) + "]");
        System.out.println("[" + construieste(true, true).apply(text) + "]");
    }
}

Rezultat

[  Iași  ]
[Iași]
[IAȘI]

Greșeli frecvente

  • Crezi că Function.identity() copiază obiectul. Returnează același obiect, nu o copie.
  • Folosești Function.identity() unde se cere un UnaryOperator; tipurile diferă. Pentru UnaryOperator există UnaryOperator.identity().

Comenzi înrudite

  • Function: O funcție care primește o valoare de tip T și returnează una de tip R; o apelezi cu apply.
  • 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.
  • Collectors.groupingBy: Împarte elementele în grupuri după o cheie (oraș, grupă, prima literă) și dă un Map cheie → listă sau cheie → rezultat.
  • Collectors.toMap: Construiește un Map din stream: o funcție dă cheia, alta valoarea; o a treia spune ce faci când cheia se repetă.