将列表传输到Java流中,然后删除列表的元素。发生某些错误

问题描述 投票:1回答:1
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,它在修改后会返回到流中。而且我对该原理没有清晰的了解。

java java-8 stream
1个回答
1
投票

传递给ConsumerforEach必须无干扰。解释如下。

无干扰

流使您可以对各种数据源执行可能并行的聚合操作,甚至包括非线程安全的集合(例如ArrayList)。这只有在我们可以防止流管道执行期间干扰数据源的情况下才有可能。除了转义hatch操作iterator()和spliterator()之外,执行在调用终端操作时开始,并在终端操作完成时结束。 对于大多数数据源,防止干扰意味着确保在流管道执行期间根本不修改数据源。值得注意的例外是其流是并发集合的流,这些流是专门为处理并发修改而设计的。并发流源是那些Splitter报告了CONCURRENT特性的流。

您尝试失败的替代方法是过滤原始List并创建一个新的List

List<String> filtered = 
    list.stream()
        .filter(m->!m.equals("banana"))
        .collect(Collectors.toList());
© www.soinside.com 2019 - 2024. All rights reserved.