2017-06-20 56 views
0

Java Stream Cheat SheetJava流与终端操作

通过此作弊片Java流去变异数据。

例如在下面使用的代码中,我是否正确地说 - 使用forEach终端操作数据正在发生变异?

List<Foo> fooList=new ArrayList<>(); 
fooList.stream() 
.filter(foo-> return foo.getSomeBoolean()) 
.forEach(foo->{ 
    foo.setSomeBoolean(false); 
}); 

我很困惑,forEach终端操作可以对数据产生副作用但不会改变数据吗?

有人能解释一下foreach是如何允许在这里改变数据的吗?

+6

请仔细阅读:*此数据不可突变。也就是说,**原始数据结构不会改变***您正在修改对象而不是数据源。 – shmosel

+1

来自'java.util.stream.Stream'的doc:'声明性地描述它们的来源以及将在该来源上聚合执行的计算操作'。使用'filter'方法,您可以将Stream转换为另一个Stream,并使用forEach来遍历流中的所有元素。 'forEach'是终端操作。 –

+0

编译器不会反对,甚至在运行时没有异常的事实都不能证明某个特定操作是被允许的。唯一重要的是正式的规范。请注意,如果源'List'中出现多次相同的'Foo'实例,则不会修改源集合,但仍可能*具有干扰。 – Holger

回答

1

你不能改变fooList,但你可以使用终端操作对元素执行副作用。正如作弊表所说的,流是一条管道线,而不是数据结构。你不能改变那些不是数据结构的东西,但是你可以操作流过流水线的单个元素。