Dans Java 8, les méthodes peuvent être créées sous forme d'expressions Lambda et peuvent être transmises par référence (avec un peu de travail sous le capot). Il existe de nombreux exemples en ligne avec des lambdas créés et utilisés avec des méthodes, mais aucun exemple sur la façon de créer une méthode prenant un lambda comme paramètre. Quelle est la syntaxe pour cela?
MyClass.method((a, b) -> a+b);
class MyClass{
//How do I define this method?
static int method(Lambda l){
return l(5, 10);
}
}
Réponses:
Les lambdas sont purement une construction de site d'appel: le destinataire du lambda n'a pas besoin de savoir qu'un lambda est impliqué, mais accepte une interface avec la méthode appropriée.
En d'autres termes, vous définissez ou utilisez une interface fonctionnelle (c'est-à-dire une interface avec une seule méthode) qui accepte et renvoie exactement ce que vous voulez.
Pour cela, Java 8 est livré avec un ensemble de types d'interfaces couramment utilisés dans
java.util.function
(merci à Maurice Naftalin pour l'astuce sur le JavaDoc).Pour ce cas d'utilisation spécifique , il y a
java.util.function.IntBinaryOperator
avec une seuleint applyAsInt(int left, int right)
méthode , vous pouvez écrire votremethod
comme ceci:Mais vous pouvez tout aussi bien définir votre propre interface et l'utiliser comme ceci:
L'utilisation de votre propre interface présente l'avantage que vous pouvez avoir des noms qui indiquent plus clairement l'intention.
la source
(int a, int b, int c)
pourTwoArgIntOperator
. Que se passe-t-il siTwoArgIntOperator
a deux méthodes avec la même signature. Cette réponse prête à confusion.Pour utiliser l'expression Lambda, vous devez soit créer votre propre interface fonctionnelle, soit utiliser l'interface fonctionnelle Java pour les opérations qui nécessitent deux entiers et renvoyer comme valeur. IntBinaryOperator
Utilisation d'une interface fonctionnelle définie par l'utilisateur
Utilisation de l'interface fonctionnelle Java
Un autre exemple que j'ai créé est ici
la source
IntBinaryOperator
documentation est mort.Pour les fonctions qui n'ont pas plus de 2 paramètres, vous pouvez les passer sans définir votre propre interface. Par exemple,
Dans
BiFunction<Integer, String, List<String>>
,Integer
etString
sont ses paramètres, etList<String>
est son type de retour.Pour une fonction avec un seul paramètre, vous pouvez utiliser
Function<T, R>
, oùT
est son type de paramètre etR
son type de valeur de retour. Reportez-vous à cette page pour toutes les interfaces déjà mises à disposition par Java.la source
Il existe une version publique accessible sur le Web des JavaDocs Java 8 compatibles Lambda, liée depuis http://lambdafaq.org/lambda-resources . (Cela devrait évidemment être un commentaire sur la réponse de Joachim Sauer, mais je ne peux pas accéder à mon compte SO avec les points de réputation dont j'ai besoin pour ajouter un commentaire.) Le site lambdafaq (je le maintiens) répond à cela et à beaucoup d'autres Java -lambda questions.
NB Cette réponse a été écrite avant que la documentation Java 8 GA ne soit rendue publique . J'ai laissé en place, cependant, car la FAQ Lambda pourrait toujours être utile aux personnes qui découvrent les fonctionnalités introduites dans Java 8.
la source
Pour moi, la solution la plus logique est de définir une
Callback
interface:puis de l'utiliser comme paramètre dans la fonction que vous souhaitez appeler:
Mais juste une précision
Un lambda n'est pas une interface spéciale, une classe ou tout autre élément que vous pouvez déclarer vous-même.
Lambda
est juste le nom donné à la() -> {}
syntaxe spéciale, qui permet une meilleure lisibilité lors du passage d'interfaces mono-méthode en paramètre. Il a été conçu pour remplacer ceci:Donc, dans l'exemple ci-dessus, ce
Callback
n'est pas un lambda, c'est juste une interface régulière;lambda
est le nom de la syntaxe de raccourci que vous pouvez utiliser pour l'implémenter.la source
Pour quiconque cherche sur Google, une bonne méthode serait d'utiliser
java.util.function.BiConsumer
. ex:L'outprint serait: 166
la source
Consumer<Pair<A,B>>
, utilisezBiConsumer<A,B>
pour ce cas. ( docs )L'expression lambda peut être passée comme argument. Pour passer une expression lambda comme argument, le type du paramètre (qui reçoit l'expression lambda comme argument) doit être de type interface fonctionnelle.
S'il y a une interface fonctionnelle -
Et il existe une méthode de filtrage qui ajoute l'int dans la liste uniquement s'il est supérieur à 5. Notez ici que la méthode de filtrage a l'interface fonctionnelle IMyFunc comme l'un des paramètres. Dans ce cas, l'expression lambda peut être passée comme argument pour le paramètre de méthode.
la source
Vous pouvez utiliser des interfaces fonctionnelles comme mentionné ci-dessus. voici quelques exemples
J'espère que cela aide
la source
Eh bien, c'est facile. Le but de l'expression lambda est d'implémenter l'interface fonctionnelle. C'est l'interface avec une seule méthode. Voici un article génial sur les interfaces fonctionnelles prédéfinies et héritées.
Quoi qu'il en soit, si vous souhaitez implémenter votre propre interface fonctionnelle, faites-le. Juste pour un exemple simple:
Faisons donc une classe, où nous allons créer une méthode, qui accepte le type de MyFunctionalInterface :
La dernière chose à faire est de passer l'implémentation de MyFunctionalInterface à la méthode que nous avons définie:
C'est ça!
la source
Lambda n'est pas un objet mais une interface fonctionnelle. On peut définir autant d'interfaces fonctionnelles que possible en utilisant @FuntionalInterface comme annotation
La sortie sera la suivante
Le concept de base d'une expression Lambda consiste à définir votre propre logique mais des arguments déjà définis. Ainsi, dans le code ci-dessus, vous pouvez modifier la définition de la fonction do en plus de toute autre définition, mais vos arguments sont limités à 2.
la source
Fondamentalement, pour passer une expression lamda comme paramètre, nous avons besoin d'un type dans lequel nous pouvons la contenir. Tout comme une valeur entière que nous détenons dans la classe prim ou int primitive . Java n'a pas de type distinct pour l'expression lamda à la place, il utilise une interface comme type pour contenir l'argument. Mais cette interface devrait être une interface fonctionnelle .
la source
Faites ce qui suit ..
Vous avez déclaré
method(lambda l)
Tout ce que vous voulez faire, c'est créer une interface avec le nomlambda
et déclarer une méthode abstraitele nom de la méthode n'a pas d'importance ici ..
Ainsi, lorsque vous appelez
MyClass.method( (a,b)->a+b)
cette implémentation(a,b)->a+b
sera injectée dans votre méthode d'ajout d'interface. Donc, chaque fois que vous appelez,l.add
elle prendra cette implémentation et effectuera l'ajout dea
etb
etreturn l.add(2,3)
reviendra5
. - Fondamentalement, c'est ce que fait lambda ..la source
Voici à peu près comment C # gère ce problème (mais exprimé en code Java). Quelque chose comme ça pourrait répondre à presque tous vos besoins:
la source
Il y a une flexibilité dans l'utilisation de lambda comme paramètre. Il permet une programmation fonctionnelle en java. La syntaxe de base est
Voici un moyen, vous pouvez définir une méthode prenant l'interface fonctionnelle (lambda est utilisé) comme paramètre. une. si vous souhaitez définir une méthode déclarée à l'intérieur d'une interface fonctionnelle, disons, l' interface fonctionnelle est donnée comme argument / paramètre à une méthode appelée depuis
main()
Ci-dessus explique une utilisation particulière de l'expression lambda, il y en a plus. ref Java 8 lambda dans un lambda ne peut pas modifier la variable de lambda externe
la source