java lambda java-8

Java 8 lambdas, Function.identity() o t-> t



function t r (3)

A partir de la implementación actual de JRE, Function.identity() siempre devolverá la misma instancia, mientras que cada aparición de identifier -> identifier no solo creará su propia instancia, sino que incluso tendrá una clase de implementación distinta. Para más detalles, ver here .

La razón es que el compilador genera un método sintético que contiene el cuerpo trivial de esa expresión lambda (en el caso de x->x , equivalente al return identifier; ) y le dice al tiempo de ejecución que cree una implementación de la interfaz funcional que llama a este método. Por lo tanto, el tiempo de ejecución solo ve diferentes métodos de destino y la implementación actual no analiza los métodos para averiguar si ciertos métodos son equivalentes.

Por lo tanto, usar Function.identity() lugar de x -> x podría ahorrar algo de memoria, pero eso no debería impulsar su decisión si realmente cree que x -> x es más legible que Function.identity() .

También puede considerar que al compilar con la información de depuración habilitada, el método sintético tendrá un atributo de depuración de línea que apunta a la (s) línea (s) del código fuente que contiene la expresión lambda, por lo tanto, tiene la posibilidad de encontrar el origen de una instancia de Function particular mientras depuración Por el contrario, al encontrar la instancia devuelta por Function.identity() durante la depuración de una operación, no sabrá quién llamó a ese método y pasó la instancia a la operación.

Tengo una pregunta sobre el uso del método Function.identity() .

Imagine el siguiente código:

Arrays.asList("a", "b", "c") .stream() .map(Function.identity()) // <- This, .map(str -> str) // <- is the same as this. .collect(Collectors.toMap( Function.identity(), // <-- And this, str -> str)); // <-- is the same as this.

¿Hay alguna razón por la que deba usar Function.identity() lugar de str->str (o viceversa). Creo que la segunda opción es más legible (una cuestión de gustos, por supuesto). Pero, ¿hay alguna razón "real" por la que uno debería ser preferido?


De la fuente JDK :

static <T> Function<T, T> identity() { return t -> t; }

Entonces, no, siempre que sea sintácticamente correcto.


En su ejemplo, no hay una gran diferencia entre str -> str y Function.identity() ya que internamente es simplemente t->t .

Pero a veces no podemos usar Function.identity porque no podemos usar una Function . Echa un vistazo aquí:

List<Integer> list = new ArrayList<>(); list.add(1); list.add(2);

esto compilará bien

int[] arrayOK = list.stream().mapToInt(i -> i).toArray();

pero si intentas compilar

int[] arrayProblem = list.stream().mapToInt(Function.identity()).toArray();

obtendrá un error de compilación ya que mapToInt espera ToIntFunction , que no está relacionado con Function . Además, ToIntFunction no tiene el método de identity() .