无法在一个流中制作过滤器->forEach->collect?

2022-01-22 00:00:00 lambda java-8 java java-stream

我想实现这样的目标:

items.stream()
    .filter(s-> s.contains("B"))
    .forEach(s-> s.setState("ok"))
.collect(Collectors.toList());

过滤,然后更改过滤结果的属性,然后将结果收集到列表中.但是,调试器说:

filter, then change a property from the filtered result, then collect the result to a list. However, the debugger says:

无法在原始类型 void 上调用 collect(Collectors.toList()).

Cannot invoke collect(Collectors.toList()) on the primitive type void.

我需要 2 个流吗?

推荐答案

forEach 被设计为终端操作,是的 - 之后你不能做任何事情你叫它.

The forEach is designed to be a terminal operation and yes - you can't do anything after you call it.

惯用的方法是先应用转换,然后 collect() 将所有内容应用于所需的数据结构.

The idiomatic way would be to apply a transformation first and then collect() everything to the desired data structure.

可以使用专为非变异操作设计的 map 执行转换.

The transformation can be performed using map which is designed for non-mutating operations.

如果您正在执行非变异操作:

 items.stream()
   .filter(s -> s.contains("B"))
   .map(s -> s.withState("ok"))
   .collect(Collectors.toList());

其中 withState 是一种返回原始对象副本的方法,包括提供的更改.

where withState is a method that returns a copy of the original object including the provided change.

如果您正在执行副作用:

items.stream()
  .filter(s -> s.contains("B"))
  .collect(Collectors.toList());

items.forEach(s -> s.setState("ok"))

相关文章