J'essaie de changer certaines boucles for-each en méthodes lambda forEach()
- pour découvrir les possibilités des expressions lambda. La suite semble être 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 un problème dans la syntaxe de la dernière ligne ou est-il impossible de renvoyer depuis la méthode forEach()
?
La return
il retourne à partir de l'expression lambda plutôt que de la méthode contenant. Au lieu de forEach
vous devez filter
le flux:
players.stream().filter(player -> player.getName().contains(name))
.findFirst().orElse(null);
Ici, filter
limite le flux aux éléments correspondant au prédicat, et findFirst
renvoie alors un Optional
avec la première entrée correspondante.
Cela semble moins efficace que l'approche par boucle, mais en fait, findFirst()
peut court-circuiter - il ne génère pas l'intégralité du flux filtré et n'en extrait ensuite un élément, mais il filtre uniquement le nombre d'éléments doit pour trouver le premier correspondant. Vous pouvez également utiliser findAny()
au lieu de findFirst()
si vous ne vous souciez pas nécessairement d'obtenir le joueur premier correspondant du flux (commandé), mais simplement tout élément correspondant. Cela permet une meilleure efficacité en cas de parallélisme.
Je vous suggère d’essayer d’abord de comprendre Java 8 dans son ensemble, le plus important dans votre cas ce seront les flux, les lambdas et les références de méthodes.
Vous devriez ne jamais convertir le code existant en code Java 8 sur une base ligne par ligne, vous devez extraire les entité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:
List<Player> playersOfTeam = players.stream()
.filter(player -> player.getTeam().equals(teamName))
.collect(Collectors.toList());
Ce que vous faites ici est:
Collection<Player>
, vous avez maintenant un Stream<Player>
.Predicate<Player>
, en mappant chaque joueur sur le booléen true si vous souhaitez le conserver.Collector
, nous pouvons utiliser ici l'un des collecteurs de bibliothèque standard, qui est Collectors.toList()
.Cela intègre également deux autres points:
List<E>
sur ArrayList<E>
.new ArrayList<>()
, vous utilisez Java 8 après tout.Passons maintenant à votre deuxième point:
Vous voulez encore une fois convertir quelque chose d'héritage Java en Java 8 sans regarder l'image plus grande. @ IanRoberts a déjà répondu à cette partie, bien que je pense que vous devez faire players.stream().filter(...)...
au-dessus de ce qu'il a suggéré.
Si vous voulez renvoyer une valeur booléenne, vous pouvez utiliser quelque chose comme ceci (beaucoup plus rapidement que filter):
players.stream().anyMatch(player -> player.getName().contains(name));
C'est ce qui m'a aidé:
List<RepositoryFile> fileList = response.getRepositoryFileList();
RepositoryFile file1 = fileList.stream().filter(f -> f.getName().contains("my-file.txt")).findFirst().orElse(null);
Extrait de Java 8 Recherche d'un élément spécifique dans la liste avec Lambda