Java 8 Lambda Stream forEach avec plusieurs instructions
Je suis toujours en train d'apprendre le Lambda, veuillez m'excuser si je fais quelque chose de mal
final Long tempId = 12345L;
List<Entry> updatedEntries = new LinkedList<>();
for (Entry entry : entryList) {
entry.setTempId(tempId);
updatedEntries.add(entityManager.update(entry, entry.getId()));
}
//entryList.stream().forEach(entry -> entry.setTempId(tempId));
Semble que forEach
ne peut être exécuté que pour une seule instruction. Il ne renvoie pas de flux ou de fonction mis à jour pour traiter davantage. J'ai peut-être sélectionné un mauvais en tout.
Quelqu'un Peut-il me guider comment le faire efficacement?
Encore Une question,
public void doSomething() throws Exception {
for(Entry entry: entryList){
if(entry.getA() == null){
printA() throws Exception;
}
if(entry.getB() == null){
printB() throws Exception;
}
if(entry.getC() == null){
printC() throws Exception;
}
}
}
//entryList.stream().filter(entry -> entry.getA() == null).forEach(entry -> printA()); something like this?
Comment convertir cela en expression Lambda?
4 answers
Oublié de se rapporter au premier extrait de code. Je n'utiliserais pas forEach
du tout. Puisque vous collectez les éléments du Stream
dans un List
, il serait plus logique de terminer le traitement Stream
avec collect
. Ensuite, vous auriez besoin de peek
pour définir l'ID.
List<Entry> updatedEntries =
entryList.stream()
.peek(e -> e.setTempId(tempId))
.collect (Collectors.toList());
Pour le deuxième extrait, forEach
pouvez exécuter plusieurs expressions, comme toute expression lambda peut :
entryList.forEach(entry -> {
if(entry.getA() == null){
printA();
}
if(entry.getB() == null){
printB();
}
if(entry.getC() == null){
printC();
}
});
Cependant (en regardant votre tentative commentée), vous ne pouvez pas utiliser le filtre dans ce scénario, puisque vous ne traiter des entrées (par exemple, les entrées pour lesquelles entry.getA() == null
) si vous ne.
Dans le premier cas, alternativement à multiline forEach
, vous pouvez utiliser l'opération de flux peek
:
entryList.stream()
.peek(entry -> entry.setTempId(tempId))
.forEach(updatedEntries.add(entityManager.update(entry, entry.getId())));
Dans le second cas, je suggérerais d'extraire le corps de la boucle dans la méthode séparée et d'utiliser la référence de la méthode pour l'appeler via forEach
. Même sans lambdas, cela rendrait votre code plus clair car le corps de la boucle est un algorithme indépendant qui traite l'entrée unique, il pourrait donc être utile à d'autres endroits et peut être testé séparément.
mise à Jour après la question édition . si vous avez coché des exceptions, vous avez deux options: soit les changer en non cochées, soit ne pas utiliser de lambdas/streams sur ce morceau de code.
List<String> items = new ArrayList<>();
items.add("A");
items.add("B");
items.add("C");
items.add("D");
items.add("E");
//lambda
//Output : A,B,C,D,E
items.forEach(item->System.out.println(item));
//Output : C
items.forEach(item->{
System.out.println(item);
System.out.println(item.toLowerCase());
}
});
Vous n'avez pas à entasser plusieurs opérations dans un flux/lambda. Envisagez de les séparer en 2 instructions (en utilisant l'importation statique de toList()
):
entryList.forEach(e->e.setTempId(tempId));
List<Entry> updatedEntries = entryList.stream()
.map(e->entityManager.update(entry, entry.getId()))
.collect(toList());