带有多个语句的 Java 8 Lambda Stream forEach

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31130457/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 10:41:07  来源:igfitidea点击:

Java 8 Lambda Stream forEach with multiple statements

javalambdajava-8

提问by Reddy

I am still in the process of learning Lambda, please excuse me If I am doing something wrong

我还在学习Lambda中,如果我做错了什么,请见谅

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));

Seems like forEachcan be executed for one statement only. It doesn't return updated stream or function to process further. I might have selected wrong one altogether.

似乎forEach只能为一个语句执行。它不会返回更新的流或函数来进一步处理。我可能完全选错了。

Can someone guide me how to do this effectively?

有人可以指导我如何有效地做到这一点吗?

One more 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?

How do I convert this to Lambda expression?

如何将其转换为 Lambda 表达式?

采纳答案by Eran

Forgot to relate to the first code snippet. I wouldn't use forEachat all. Since you are collecting the elements of the Streaminto a List, it would make more sense to end the Streamprocessing with collect. Then you would need peekin order to set the ID.

忘记涉及第一个代码片段。我根本不会用forEach。由于您正在将 的元素收集Stream到 a 中List,因此以 结束Stream处理会更有意义collect。然后,您需要peek设置 ID。

List<Entry> updatedEntries = 
    entryList.stream()
             .peek(e -> e.setTempId(tempId))
             .collect (Collectors.toList());

For the second snippet, forEachcan execute multiple expressions, just like any lambda expression can :

对于第二个代码段,forEach可以执行多个表达式,就像任何 lambda 表达式都可以:

entryList.forEach(entry -> {
  if(entry.getA() == null){
    printA();
  }
  if(entry.getB() == null){
    printB();
  }
  if(entry.getC() == null){
    printC();
  }
});

However (looking at your commented attempt), you can't use filter in this scenario, since you will only process some of the entries (for example, the entries for which entry.getA() == null) if you do.

但是(查看您评论的尝试),您不能在这种情况下使用过滤器,因为entry.getA() == null如果您这样做,您将只处理某些条目(例如, which 的条目)。

回答by Tagir Valeev

In the first case alternatively to multiline forEachyou can use the peekstream operation:

在第一种情况下,forEach您可以使用peek流操作替代多行:

entryList.stream()
         .peek(entry -> entry.setTempId(tempId))
         .forEach(updatedEntries.add(entityManager.update(entry, entry.getId())));

In the second case I'd suggest to extract the loop body to the separate method and use method reference to call it via forEach. Even without lambdas it would make your code more clear as the loop body is independent algorithm which processes the single entry so it might be useful in other places as well and can be tested separately.

在第二种情况下,我建议将循环体提取到单独的方法中,并使用方法引用通过forEach. 即使没有 lambda,它也会使您的代码更加清晰,因为循环体是处理单个条目的独立算法,因此它在其他地方也可能有用并且可以单独测试。

Update after question editing. if you have checked exceptions then you have two options: either change them to unchecked ones or don't use lambdas/streams at this piece of code at all.

问题编辑后更新。如果您有已检查的异常,那么您有两个选择:要么将它们更改为未检查的异常,要么在这段代码中根本不使用 lambdas/streams。

回答by Misha

You don't have to cram multiple operations into one stream/lambda. Consider separating them into 2 statements (using static import of toList()):

您不必将多个操作塞进一个流/lambda 中。考虑将它们分成 2 个语句(使用 的静态导入toList()):

entryList.forEach(e->e.setTempId(tempId));

List<Entry> updatedEntries = entryList.stream()
  .map(e->entityManager.update(entry, entry.getId()))
  .collect(toList());

回答by user3060544

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());
  }
});