118 votes

Ce n'lambda avec 2 flèches signifient dans Java 8?

J'ai lu plusieurs de Java 8 tutoriels avant.

Maintenant, j'ai rencontré rubrique suivante: Ne le support de java Nourrissage?

Ici, je vois le code suivant:

IntFunction<IntUnaryOperator> curriedAdd = a -> b -> a + b;
System.out.println(curriedAdd.apply(1).applyAsInt(12));

Je comprends que cet exemple, la somme de 2 éléments, mais je ne peux pas comprendre la construction:

a -> b -> a + b;

Selon la partie gauche de l'expression, cette ligne devrait mettre en œuvre la fonction suivante:

R apply(int value); 

Avant cela, je ne l'ai rencontré lambdas avec une seule flèche.

118voto

Adam Points 5429

Si vous exprimez ce que la non-abrégée lambda de syntaxe ou de pré-lambda Java la classe anonyme de la syntaxe, il est plus clair ce qui se passe...

La question d'origine. Pourquoi sont deux flèches? Simple, il existe deux fonctions étant défini... La première fonction est une fonction de la définition de fonction, le deuxième est le résultat de cette fonction, qui se trouve être une fonction. Chacun exige une -> de l'opérateur de le définir.

Non-sténographie

IntFunction<IntUnaryOperator> curriedAdd = (a) -> {
    return (b) -> {
        return a + b;
    };
};

Pré-Lambda avant Java 8

IntFunction<IntUnaryOperator> curriedAdd = new IntFunction<IntUnaryOperator>() {
    @Override
    public IntUnaryOperator apply(final int value) {
        IntUnaryOperator op = new IntUnaryOperator() {
            @Override
            public int applyAsInt(int operand) {
                return operand + value;
            }
        };
        return op;
    }
};

48voto

ZouZou Points 23600

Un IntFunction<R> est une fonction int -> R. Un IntUnaryOperator est une fonction int -> int.

Ainsi, un IntFunction<IntUnaryOperator> est une fonction qui prend un int comme paramètre et retourne une fonction qui prend un int en paramètre et retourne un int.

a -> b -> a + b;
^    |         |
|     ---------
|         ^
|         |
|         The IntUnaryOperator (that takes an int, b) and return an int (the sum of a and b)
|
The parameter you give to the IntFunction

C'est peut-être plus clair si vous utilisez anonyme classes à "décomposer" la lambda:

IntFunction<IntUnaryOperator> add = new IntFunction<IntUnaryOperator>() {
    @Override
    public IntUnaryOperator apply(int a) {
        return new IntUnaryOperator() {
            @Override
            public int applyAsInt(int b) {
                return a + b;
            }
        };
    }
};

29voto

Tagir Valeev Points 14218

L'ajout de parenthèses peut que cela soit plus clair:

IntFunction<IntUnaryOperator> curriedAdd = a -> (b -> (a + b));

Ou probablement variable intermédiaire peut aider:

IntFunction<IntUnaryOperator> curriedAdd = a -> {
    IntUnaryOperator op = b -> a + b;
    return op;
};

24voto

Tunaki Points 2663

Réécrivons que la lambda expression avec parenthèses pour rendre cela plus clair:

IntFunction<IntUnaryOperator> curriedAdd = a -> (b -> (a + b));

Nous sommes donc déclarer une fonction prenant un int qui retourne un Function. Plus précisément, la fonction renvoyée prend un int et renvoie un int (la somme des deux éléments): ceci peut être représenté comme un IntUnaryOperator.

Par conséquent, curriedAdd est une fonction prenant un int et au retour d'une IntUnaryOperator, de sorte qu'il peut être représenté comme IntFunction<IntUnaryOperator>.

9voto

zeroflagL Points 7379

C'est deux expressions lambda.

IntFunction<IntUnaryOperator> curriedAdd = 
  a -> { //this is for the fixed value
    return b -> { //this is for the add operation
      return a + b;
    };
  }

IntUnaryOperator addTwo = curriedAdd.apply(2);
System.out.println(addTwo.applyAsInt(12)); //prints 14

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X