Interface AccountService{
public void createAccount();
}
AccountService accountServiceAnonymous = new AccountService(){
public void createAccount(){
Account account = new Account();
save(account);
}
};
AccountService accountServiceLambda = () -> {
Account account = new Account();
save(account);
}
Outre le nombre réduit de lignes de code, l'utilisation des expressions lambda dans Java 8 offre-t-elle d'autres avantages?
Ajout à ce que @Bilbo a mentionné dans les commentaires. Dans Java 1.7, un nouveau code d'opération JVM appelé invokedynamic
a été publié et Java 8 Lambda l'utilise. Ainsi, le code suivant entraînera la création d'une classe anonyme lors de la compilation du code. <ClassName>$1.class
possible donc si vous avez 10 classes anonymes, c’est 10 classes supplémentaires dans le dernier fichier.
AccountService accountServiceAnonymous = new AccountService(){
public void createAccount(){
Account account = new Account();
save(account);
}
};
Mais Java 8 lambda utilise invokedynamic
pour appeler lambdas. Ainsi, si vous avez 10 lambdas, aucune classe anonyme ne sera créée, ce qui réduira la taille finale du fichier jar.
AccountService accountServiceLambda = () -> {
Account account = new Account();
save(account);
}
Un autre avantage des lambdas (et des références de méthodes) est visible lorsque vous les combinez avec Stream API et d'autres fonctionnalités ajoutées à Java 8, par exemple. Optionnel.
Considérons ce code:
private void pushToFront(AbstractInfo contactInfo) {
registeredWindows.stream()
.filter(window -> window.getWindowId() == contactInfo.getId())
.findAny()
.ifPresent(Window::pushToFront);
}
La méthode filtre la liste des fenêtres enregistrées correspondant à windowId avec l'identifiant du contact renvoyant un facultatif. Si la liste contient une fenêtre avec un identifiant correspondant, la valeur dans Optional est présente et la méthode pushToFront s'y trouve. Comparez cela à la même fonctionnalité mais écrite en Java 7:
private void pushToFront(AbstractInfo contactInfo) {
for (Window window : registeredWindows) {
if (window.getWindowId() == contactInfo.getId() {
window.pushToFront();
}
}
}
Le code avec l'expression lambda, le flux et la référence de méthode, du moins pour moi, est plus concis et lisible (quand on s'habitue à utiliser des flux). L'exemple ci-dessus est assez simple - mais prenons un exemple qui, dans Java 7, nécessiterait des boucles imbriquées, plusieurs instructions conditionnelles, etc. Il est difficile de lire encore plus difficilement pour ne pas perdre de vue ce qui se passe.
Lambdas permet ensuite d’utiliser pleinement les autres fonctionnalités de Java 8, qui permettent, entre autres, d’obtenir un code net, propre, efficace et facile à comprendre.
En bout de ligne, vous devriez considérer les expressions lambda comme faisant partie d’un ensemble plus vaste, ce qui est excellent pour elles-mêmes mais encore mieux lorsque combiné à d’autres «blocs de construction» de Java 8.
Encore une fois - contrairement aux classes anonymes, les lambdas NE créent PAS de nouvelle portée, ils partagent la même portée que le bloc/environnement englobant.
Alors:
Il est plus facile d'accéder à l'objet englobant - la référence plain this
fait référence à l'instance de la classe englobante (et vous n'avez pas besoin de dire EnclosingClass.this
)
Il n'y a pas de shadowing (vous ne pouvez pas définir de variables locales portant les mêmes noms que les variables dans la portée englobante)
Avantages des expressions lambda
En plus de ce qui a été dit ici et pour répondre strictement à la question posée, il est important de voir lambdas comme un "bloc de code" pouvant, entre autres, être passé en paramètre. Cela procure un énorme avantage car vous pouvez supprimer le code dupliqué.
Comment c'est ? Dans l'exemple ci-dessus présenté par @Kitke, la méthode pushToFront (...), si l'exigence existe, peut être refactorisée un peu en tant que modèle et utilisée pour filtrer registeredWindows par toute condition . L'expression lambda window -> window.getWindowId () == contactInfo.getId (), peut être transmise en tant que paramètre dans ce cas. Sans cette fonctionnalité puissante, vous devez écrire la boucle while à chaque fois que vous devez filtrer la collection registeredWindows selon une condition différente. Énorme avantage, repensez votre code en gardant cela à l'esprit.
Extrait de: http://www.copypasteisforword.com/notes/lambda-expressions-in-Java . Vous y trouverez un autre exemple d'utilisation de lambda pour supprimer le code dupliqué.