java 8流干扰与非干扰

Ara*_*ram 5 java-8 java-stream

我理解为什么以下代码没问题.因为在调用终端操作之前正在修改集合.

List<String> wordList = ...;
Stream<String> words = wordList.stream();
wordList.add("END"); // Ok
long n = words.distinct().count();
Run Code Online (Sandbox Code Playgroud)

但为什么这段代码不合适呢?

Stream<String> words = wordList.stream();
words.forEach(s -> if (s.length() < 12) wordList.remove(s)); // Error—interference
Run Code Online (Sandbox Code Playgroud)

Joa*_*son 5

Stream.forEach() 是终端操作,并且在终端启动/调用之后修改基础wordList集合.


Stu*_*rks 5

约阿希姆的回答是正确的,+1。

您没有具体询问,但为了其他读者的利益,这里有一些技术可以以不同的方式重写程序,避免流干扰问题。

如果你想就地改变列表,你可以使用新的默认方法List而不是使用流:

wordList.removeIf(s -> s.length() < 12);
Run Code Online (Sandbox Code Playgroud)

如果您想保持原始列表不变但创建修改后的副本,您可以使用流和收集器来做到这一点:

List<String> newList = wordList.stream()
    .filter(s -> s.length() >= 12)
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

请注意,我必须反转条件的含义,因为如果条件为真,则filter采用一个保留在流中的谓词。