comportamiento diferente entre la expresión lambda y referencia método por el instanciación

st.ebberr:

Como sé que la expresión lambda puede ser sustituida por la referencia método sin ningún problema. Mis IDE dicen lo mismo, pero el siguiente ejemplo se muestra lo contrario. La referencia método devuelve claramente el mismo objeto, en donde como expresión lambda devuelve nuevos objetos cada vez.

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Instance {

    int member;

    Instance set(int value){
        this.member = value;
        return this;
    }

    @Override
    public String toString() {
        return member + "";
    }

    public static void main(String[] args) {

        Stream<Integer> stream1 = Stream.of(1, 2, 3, 4);
        Stream<Integer> stream2 = Stream.of(1, 2, 3, 4);

        List<Instance> collect1 = stream1.map(i -> new Instance().set(i)).collect(Collectors.toList());
        List<Instance> collect2 = stream2.map(new Instance()::set).collect(Collectors.toList());

        System.out.println(collect1);
        System.out.println(collect2);
    }
}

Aquí está mi salida:

[1, 2, 3, 4]
[4, 4, 4, 4]
davidxxx:

El momento de referencia método difiere evaluación de la expresión de la que de expresiones lambda.
Con una referencia método que tiene una expresión (en lugar de un tipo) que precede al ::la subexpresión se evalúa inmediatamente y el resultado de la evaluación se almacena y se reutiliza a continuación.
Así que aquí:

new Instance()::set

new Instance() se evalúa una sola vez.

De 15.12.4. Tiempo de ejecución de Evaluación de la invocación de método (el subrayado es mío):

El momento de la evaluación de la expresión de referencia método es más compleja que la de las expresiones lambda (§15.27.4). Cuando una expresión de referencia método tiene una expresión (en lugar de un tipo) que precede al :: separador, que subexpresión se evaluaron inmediatamente. El resultado de la evaluación se almacena hasta que se invoca el método del tipo de interfaz funcional correspondiente; en ese punto, el resultado se utiliza como la referencia de destino para la invocación. Esto significa que la expresión que precede a la :: separador se evalúa sólo cuando el programa llega a la expresión de referencia método, y no es re-evaluado en invocaciones posteriores sobre el tipo de interfaz funcional .

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=166041&siteId=1
Recomendado
Clasificación