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?

Author: Reddy, 2015-06-30

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.

 38
Author: Eran, 2015-06-30 09:17:56

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.

 6
Author: Tagir Valeev, 2015-06-30 05:55:04
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());
  }
});
 4
Author: user3060544, 2017-06-20 08:35:57

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());
 2
Author: Misha, 2015-06-30 06:15:26