奇怪的Java并发修改异常示例

我是 Java 8 的新手,希望了解这两种情况之间的区别。我知道一旦一个流被操作和消耗,那么流就不能再次被重用,它会给出一个错误。


场景 1:


List<String> title = Arrays.asList("Java8", "In", "Action");

        Stream<String> s = title.stream();

        s.forEach(System.out::println);

        s.forEach(System.out::println); // THIS WILL GIVE ERROR - streams has been already operated and closed.

当我运行这个时,我得到以下错误......这是公平的。


Java8

In

Action

Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed

    at java.util.stream.AbstractPipeline.sourceStageSpliterator(Unknown Source)

    at java.util.stream.ReferencePipeline$Head.forEach(Unknown Source)

    at com.test.Java8InAction.CH4.TraversableOnlyOnce.main(TraversableOnlyOnce.java:12)

场景 2:


// Filtering unique elements

List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);

numbers.stream().forEach(System.out::println);

numbers.stream().filter(n -> n % 2 == 0).distinct().forEach(System.out::println);

numbers.stream().filter(n -> n % 2 == 0).forEach(System.out::println);

这里我也操作了stream,关闭了终端操作,那为什么没有报错呢?


紫衣仙女
浏览 192回答 2
2回答

墨色风雨

List.remove()ConcurrentModificationException当它从列表中删除倒数第二个元素时不会抛出。引用此Java Bug (JDK-4902078)。当集合框架被添加到平台时,每次迭代检查一次而不是两次的共同修改被认为太昂贵了;检查是在 Iterator.next 而不是 Iterator.hasNext 上进行的。专家审稿人认为这已经足够了。他们不知道它未能检测到一个重要的情况:如果在迭代中最后一次调用 hasNext 之前立即从列表中删除了一个元素,则该调用将返回 false 并且迭代终止,默默地忽略列表中的最后一个元素。

翻过高山走不出你

有两种方法用于迭代集合:枚举和迭代器。第一个允许在迭代期间修改集合(慢速失败),第二个不允许(快速失败)。在 for-each 循环中,您使用的是迭代器,因此在迭代期间对集合的任何修改都会导致异常。您有 3 个选择来解决这个问题:改用迭代器:Iterator<String> bookIt = listOfBooks.iterator();while(bookIt.hasNext()){&nbsp; &nbsp;String book = bookIt.next();&nbsp; &nbsp;if (book.contains("Java")) {&nbsp; &nbsp; &nbsp; &nbsp;bookIt.remove();&nbsp; &nbsp;}}创建一个仅包含可接受元素的新列表(过滤掉不需要的元素):&nbsp;List<String> booksWithNoCode =&nbsp; listOfBooks.stream()&nbsp;.filter(book-> !book.contains("Code"))&nbsp;.collect(toList())使用Collection.removeIf(),您将从列表中删除所有符合给定条件的元素。listOfBooks.removeIf(book-> book.contains("Code"))您可以在这篇文章和这里找到更多信息。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java