java 8流干扰与非干扰

时间:2014-07-19 15:26:18

标签: java-8 java-stream

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

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

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

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

2 个答案:

答案 0 :(得分:5)

Stream.forEach()是一个终端操作,在终端启动/调用后修改了基础wordList集合。

答案 1 :(得分:4)

Joachim's answer是正确的,+ 1。

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

如果您想要就地改变列表,可以使用List上的新默认方法而不是使用流来执行此操作:

wordList.removeIf(s -> s.length() < 12);

如果您想保留原始列表但创建修改后的副本,可以使用流和收集器来执行此操作:

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

请注意,我必须反转条件的意义,因为如果条件为真,filter采用保持值的谓词。