J'essaie de changer certaines boucles for-each en forEach()
méthodes lambda pour découvrir les possibilités des expressions lambda. Ce qui suit semble possible:
ArrayList<Player> playersOfTeam = new ArrayList<Player>();
for (Player player : players) {
if (player.getTeam().equals(teamName)) {
playersOfTeam.add(player);
}
}
Avec lambda forEach()
players.forEach(player->{if (player.getTeam().equals(teamName)) {playersOfTeam.add(player);}});
Mais le suivant ne fonctionne pas:
for (Player player : players) {
if (player.getName().contains(name)) {
return player;
}
}
avec lambda
players.forEach(player->{if (player.getName().contains(name)) {return player;}});
Y a-t-il quelque chose qui ne va pas dans la syntaxe de la dernière ligne ou est-il impossible de revenir de la forEach()
méthode?
return
dans une instruction, lambda retourne du lambda lui-même, pas de ce qu'on appelle le lambda. La terminaison d'un flux précoce ("court-circuitage") utilisefindFirst
comme indiqué dans la réponse de Ian Roberts .Réponses:
Il
return
y a un retour de l'expression lambda plutôt que de la méthode contenant. Au lieu deforEach
vous avez besoinfilter
du flux:Ici
filter
restreint le flux aux éléments qui correspondent au prédicat,findFirst
puis renvoie unOptional
avec la première entrée correspondante.Cela semble moins efficace que l'approche de la boucle for, mais en fait
findFirst()
peut court-circuiter - il ne génère pas le flux filtré entier et n'en extrait pas un élément, mais filtre uniquement autant d'éléments qu'il le faut pour trouvez le premier correspondant. Vous pouvez également utiliser à lafindAny()
place defindFirst()
si vous ne vous souciez pas nécessairement d'obtenir le premier joueur correspondant à partir du flux (ordonné), mais simplement n'importe quel élément correspondant. Cela permet une meilleure efficacité en cas de parallélisme.la source
orElse(null)
sur un fichierOptional
. Le point principal deOptional
est de fournir un moyen d'indiquer la présence ou l'absence d'une valeur au lieu de surcharger null (ce qui conduit à des NPE). Si vous l'utilisez,optional.orElse(null)
il rachète tous les problèmes avec les valeurs nulles. Je ne l'utiliserais que si vous ne pouvez pas modifier l'appelant et qu'il attend vraiment un null.Optional<Player>
serait un moyen plus naturel de s'intégrer dans le paradigme des flux. J'essayais juste de montrer comment dupliquer le comportement existant à l'aide de lambdas.Je vous suggère d'essayer d'abord de comprendre Java 8 dans son ensemble, le plus important dans votre cas, ce sera les flux, les lambdas et les références de méthodes.
Vous ne devez jamais convertir du code existant en code Java 8 ligne par ligne, vous devez extraire les fonctionnalités et les convertir.
Ce que j'ai identifié dans votre premier cas est le suivant:
Voyons comment nous faisons cela, nous pouvons le faire avec ce qui suit:
Ce que vous faites ici est:
Collection<Player>
, maintenant vous avez un fichierStream<Player>
.Predicate<Player>
, mappant chaque joueur sur le booléen true s'il est souhaité qu'il soit conservé.Collector
, ici, nous pouvons utiliser l'un des collecteurs de bibliothèque standard, qui estCollectors.toList()
.Cela intègre également deux autres points:
List<E>
overArrayList<E>
.new ArrayList<>()
, vous utilisez Java 8 après tout.Passons maintenant à votre deuxième point:
Vous voulez à nouveau convertir quelque chose de Java hérité en Java 8 sans regarder la situation dans son ensemble. @IanRoberts a déjà répondu à cette partie , même si je pense que vous devez faire
players.stream().filter(...)...
ce qu'il a suggéré.la source
Si vous souhaitez renvoyer une valeur booléenne, vous pouvez utiliser quelque chose comme ceci (beaucoup plus rapide que le filtre):
la source
C'est ce qui m'a aidé:
Tiré de Java 8 Recherche d'un élément spécifique dans la liste avec Lambda
la source
Vous pouvez également lever une exception:
Remarque:
Pour des raisons de lisibilité, chaque étape du flux doit être répertoriée dans une nouvelle ligne.
si votre logique est vaguement "pilotée par les exceptions", par exemple, il y a un endroit dans votre code qui intercepte toutes les exceptions et décide quoi faire ensuite. N'utilisez le développement axé sur les exceptions que lorsque vous pouvez éviter de joncher votre base de code avec des multiples
try-catch
et de lever ces exceptions pour des cas très particuliers dans lesquels vous les attendez et peuvent être gérés correctement.)la source