comportement différent entre l'expression lambda et la référence de procédé par instanciation

st.ebberr:

Comme je sais que l'expression lambda peut être remplacée par une référence de méthode sans aucun problème. Mes IDEs disent la même chose, mais l'exemple suivant montre le contraire. La référence de méthode renvoie clairement le même objet, alors que de nouveaux objets retourne à chaque fois que l'expression lambda.

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);
    }
}

Voici ma sortie:

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

Le moment de l' évaluation de l' expression de référence qui diffère de la méthode des expressions lambda.
Avec une référence de procédé qui a une expression (plutôt que d' un type) précédant le ::la sous - expression est évaluée immédiatement et le résultat de l' évaluation est stocké et réutilisé ensuite.
Alors , voici:

new Instance()::set

new Instance() est évaluée une seule fois.

De 15.12.4. Run-Time évaluation de la méthode Invocation (souligné dans l' original ):

Le moment de l' évaluation des expressions de référence de la méthode est plus complexe que celle des expressions lambda (§15.27.4). Quand une expression de référence du procédé présente une expression (plutôt que d' un type) précédant le séparateur ::, ce sous - expression est évaluée immédiatement. Le résultat de l' évaluation est stocké jusqu'à ce que le procédé du type d'interface fonctionnelle correspondante est appelée; à ce moment, le résultat est utilisé comme référence de cible pour l'appel. Cela signifie que l'expression qui précède le séparateur :: est évalué uniquement lorsque le programme rencontre le procédé expression de référence, et n'a pas réévalué sur invocations ultérieures sur le type d'interface fonctionnelle .

Je suppose que tu aimes

Origine http://43.154.161.224:23101/article/api/json?id=166039&siteId=1
conseillé
Classement