为什么用流过滤器偷看编辑列表收集工作?

时间:2019-03-27 23:15:37

标签: java stream

我写了一些代码,我不明白为什么它起作用,我找不到明确的答案。这是我的代码:

    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列表。

1 个答案:

答案 0 :(得分:1)

您的employees列表包含对每个Employee元素的引用。流只是简单地遍历那些引用,并将它们通过管道。您的peek操作具有side-effect,可以修改Employee允许的每个filter的position属性。您引用这些Employee实例的任何地方都会看到该修改,包括原始的employees列表。有关更多信息,请参见Is Java "pass-by-reference" or "pass-by-value"?

在您添加对collect的呼叫之前您看不到任何更改的原因是因为collectterminal operation,而filterpeek不是。 Stream在调用终端操作之前不会执行。