Maison  >  Article  >  Java  >  Pourquoi mon lambda forEach ne me permet-il pas de quitter ma fonction avec une instruction return en Java ?

Pourquoi mon lambda forEach ne me permet-il pas de quitter ma fonction avec une instruction return en Java ?

Barbara Streisand
Barbara Streisandoriginal
2024-09-26 07:06:42783parcourir

Why won

Disons que vous avez un panier de nourriture :

List<Food> basket = List.of(
     new Food("Apple", FRUIT),
     new Food("Banana", FRUIT),
     new Food("Carrot", VEGETABLE),
     new Food("Orange", FRUIT),
);

Et une obligation de n'accepter ce panier que s'il n'est rempli que de fruits. Pour répondre à cette exigence, vous décidez d'implémenter une boucle for :

private boolean containtsOnlyFruits(List<Food> basket) {
for (Food food : basket) {
        if (food.getFoodType() != FRUIT) {
            return false;
        }
    }
    return true;
}

Ensuite, vous vous souvenez que vous avez découvert Java Lambdas et une approche plus fonctionnelle, vous décidez donc d'écrire la même chose dans un lambda forEach :

private boolean containtsOnlyFruits(List<Food> basket) {
    basket.forEach(food -> {
        if (food.getFoodType() != FRUIT) {
            return false;
        }
    });
    return true;
}

Juste pour tomber sur une erreur :

valeur de retour inattendue

Pourquoi ça ?

Un lambda n'est rien de plus qu'une fonction. Dans ce cas, une fonction anonyme, ou en d’autres termes, une fonction sans nom. Comme toute autre fonction, un lambda peut recevoir des arguments et également s'attendre à ce que quelque chose soit renvoyé.

Lorsque vous essayez de renvoyer false à partir du lambda forEach, vous essayez en fait de quitter cette fonction anonyme et de générer un booléen. Cependant, la fonction forEach ne devrait renvoyer aucun résultat. Ce n'est tout simplement pas ainsi que cette fonction est implémentée.

En fait, si vous regardez l'implémentation de la fonction forEach, vous verrez qu'elle accepte un Consumer :

default void forEach(Consumer<? super T> action) {
    Objects.requireNonNull(action);
    for (T t : this) {
        action.accept(t);
    }
}

Un consommateur est une interface qui représente une opération qui accepte un seul argument d'entrée et ne renvoie aucun résultat. Dans cette implémentation, vous pouvez voir que sous le capot, la fonction forEach utilise une boucle for each, effectuant l'action donnée et ne renvoyant rien.

Donc pour satisfaire notre fonctionnement dans une approche fonctionnelle, il nous faudra trouver un autre lambda. Il y a un bon candidat ici : allMatch.

Avec le lambda allMatch, on peut vérifier si tous les éléments du panier sont un fruit :

private boolean onlyFruits(List<Food> basket) {
    return basket.stream().allMatch(food -> food.getFoodType() == FRUIT);
}

Si tel est le cas, notre lambda retournera vrai. Et si l'on regarde l'intérieur d'allMatch :

boolean allMatch(Predicate<? super T> predicate);

Nous verrons que la fonction allMatch attend un Prédicat.

Un prédicat est une interface fonctionnelle tout comme un consommateur, mais il fonctionne un peu différemment. Alors qu'un consommateur représente une opération qui accepte un seul argument d'entrée et ne renvoie aucun résultat, un prédicat représente un prédicat (fonction à valeur booléenne) d'un argument utilisé pour tester un objet pour une condition et renvoyer une valeur booléenne (vrai ou faux). ).

Il existe d'autres interfaces fonctionnelles très importantes. Pouvez-vous me dire ce qu'ils sont et comment ils fonctionnent ?

Restez curieux !

Contribuer

Écrire demande du temps et des efforts. J'aime écrire et partager des connaissances, mais j'ai aussi des factures à payer.

Si vous aimez mon travail, envisagez de faire un don via Buy Me a Coffee : https://www.buymeacoffee.com/RaphaelDeLio

Ou en m'envoyant BitCoin : 1HjG7pmghg3Z8RATH4aiUWr156BGafJ6Zw

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn