java - 将List传输到Java Stream中,然后删除List中的一个元素。出现一些错误

标签 java java-8 java-stream

List<String> list = new ArrayList(){{add("apple");add("banana");add("orange");}};
Stream<String> stringStream = list.stream();
stringStream.forEach(
        m->{
            if (m.equals("banana")){
                list.remove("banana");
            }
        }
);
System.out.println(stringStream.count());

最后,控制台打印一个 NullPointerException 错误。 CoreJava规定我们不应该修改Collection,修改后会返回到流中。而且我也不太清楚其中的原理。

最佳答案

传递给 forEachConsumer 必须是非干扰的。下面解释一下原因。

Non-interference

Streams enable you to execute possibly-parallel aggregate operations over a variety of data sources, including even non-thread-safe collections such as ArrayList. This is possible only if we can prevent interference with the data source during the execution of a stream pipeline. Except for the escape-hatch operations iterator() and spliterator(), execution begins when the terminal operation is invoked, and ends when the terminal operation completes. For most data sources, preventing interference means ensuring that the data source is not modified at all during the execution of the stream pipeline. The notable exception to this are streams whose sources are concurrent collections, which are specifically designed to handle concurrent modification. Concurrent stream sources are those whose Spliterator reports the CONCURRENT characteristic.

( Source )

顺便说一句,即使前面的 stringStream.forEach() 语句没有失败,您的 stringStream.count() 也会失败,因为 forEach (与任何终端操作一样)会消耗 Stream,并且 Stream 不能被消耗两次。

实现您想要做的事情的正确方法是过滤原始List并创建一个新的List:

List<String> filtered = 
    list.stream()
        .filter(m->!m.equals("banana"))
        .collect(Collectors.toList());

关于java - 将List传输到Java Stream中,然后删除List中的一个元素。出现一些错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58948043/

相关文章:

java - SWT Eclipse 组合事件

java - 是否可以指定 JVM(或 IDE)使用哪个网络接口(interface)

java - 使用 .collect(toList()) 时,推理变量 T 具有不兼容的边界

Java8 类型通用删除方法签名和 lambda 不起作用

java - Guava 的 Streams::findLast 实现

java-8 - Java 8 - 嵌套 if 在循环内

java - Java 8 `Stream` 可以在您不要求的情况下并行吗?

java - 如何通过休息调用使用输入表单获取数据?

java - 在运行时清除缓存 - Eclipse e4

java-8 - 在 Java 8 流中使用返回 void 的函数