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,修改后会返回到流中。而且我也不太清楚其中的原理。
最佳答案
传递给 forEach
的 Consumer
必须是非干扰的。下面解释一下原因。
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/