我写了一些代码,我不明白为什么它起作用,我找不到明确的答案。这是我的代码:
log.debug("before");
for (Employee e : this.employees) {
log.debug(e.toString());
}
employees
.stream()
.filter(e -> e.getUuid().equals(event.getEmployeeUuid()))
.peek(e -> {
e.setPosition(event.getPosition());
}).collect(Collectors.toList());
log.debug("after");
for (Employee e : this.employees) {
log.debug(e.toString());
}
这是输出:
before
Employee(uuid=aaa, position=Lord)
Employee(uuid=bbb, position=Employee)
after
Employee(uuid=aaa, position=Overlord)
Employee(uuid=bbb, position=Employee)
所以我的一般问题是为什么它起作用?我无意中注意到了此行为,并且仅当流处理结束时出现.collect(Collectors.toList())
时才起作用。请注意,没有将流的输出显式分配给this.employees
列表。
答案 0 :(得分:1)
您的employees
列表包含对每个Employee
元素的引用。流只是简单地遍历那些引用,并将它们通过管道。您的peek
操作具有side-effect,可以修改Employee
允许的每个filter
的position属性。您引用这些Employee
实例的任何地方都会看到该修改,包括原始的employees
列表。有关更多信息,请参见Is Java "pass-by-reference" or "pass-by-value"?。
在您添加对collect
的呼叫之前您看不到任何更改的原因是因为collect
是terminal operation,而filter
和peek
不是。 Stream
在调用终端操作之前不会执行。