descargar - ¿Cuáles son los usos prácticos del método java.util.function.Function.identity?
jdk 7 (3)
¿Por qué debo usar Function.identity () cuando devuelve la misma cosa que recibe sin hacer nada usando la entrada o modificando la entrada de alguna manera?
Apple apple = new Apple(10, "green");
Function<Apple, Apple> identity = Function.identity();
identity.apply(apple);
Debe haber algún uso práctico de esto que no pueda resolver.
El uso previsto es cuando está utilizando un método que acepta una Function
para asignar algo, y necesita asignar la entrada directamente a la salida de la función (la función ''identidad'').
Como un ejemplo muy simple, mapear una lista de personas a un mapa de nombre a persona:
import static java.util.function.Function.identity
// [...]
List<Person> persons = ...
Map<String, Person> = persons.stream()
.collect(Collectors.toMap(Person::name, identity()))
La función de identity()
es solo por conveniencia y legibilidad. Como indica Peter en su respuesta, puedes usar t -> t
, pero personalmente creo que usar identity()
comunica mejor, ya que no deja espacio para la interpretación, como preguntarme si el autor original se olvidó de hacer una transformación en esa lambda. Aunque admito que es altamente subjetivo, y asume que el lector sabe lo que hace la identity()
.
Posiblemente puede tener algunas ventajas adicionales en términos de memoria, ya que reutiliza una sola definición de lambda, en lugar de tener una definición específica de lambda para esta llamada. Creo que el impacto es probablemente despreciable en la mayoría de los casos.
Puedes usarlo para un conteo de frecuencia, por ejemplo.
public static <T> Map<T, Long> frequencyCount(Collection<T> words) {
return words.stream()
.collect(Collectors.groupingBy(Function.identity(),
Collectors.counting());
}
En este caso, está diciendo que la clave para agrupar es el elemento de la colección (sin transformarla).
Personalmente, me parece más breve.
import static java.util.stream.Collectors.*;
public static Map<String, Long> frequencyCount(Collection<String> words) {
return words.stream()
.collect(groupingBy(t -> t,
counting());
}
Supongamos que tiene una List<String> strings = List.of("abc", "de")
y desea generar un Map
en el que Key
es el valor de esa Lista y Valor es su longitud:
Map<String, Integer> map = strings.stream()
.collect(Collectors.toMap(Function.identity(), String::length))
En general, algunas personas ven Function.identity()
un poco menos legible que t -> t
por ejemplo, pero como se explica this esto es un poco diferente.