【问题标题】:Java: Why ConcurrentModificationException doesnt occur while using Stream+Iterator?Java:为什么在使用 Stream+Iterator 时不会发生 ConcurrentModificationException?
【发布时间】:2020-10-21 07:54:02
【问题描述】:

我正在阅读一些关于迭代器、枚举等的信息。所以我测试了一些代码来检查所有内容。

第一个例子:

List<String> list = new ArrayList<>();
list.add("5");
list.add("1");
list.add("2");
list.add("3");
Iterator<String> iterator = list.iterator();
list.remove("1");
iterator.forEachRemaining(System.out::println);

此代码产生正确且预期的输出:

Exception in thread "main" java.util.ConcurrentModificationException

但是当我测试相同的代码时只做了 1 处更改 list.iterator() -> list.stream().iterator()

List<String> list = new ArrayList<>();
list.add("5");
list.add("1");
list.add("2");
list.add("3");
Iterator<String> iterator = list.stream().iterator();
list.remove("1");
iterator.forEachRemaining(System.out::println);

结果是:

5
2
3

我的主要目的是了解:

  1. 为什么会这样?
  2. 什么魔法使只有一个stream() 方法?
  3. 使用stream().iterator的优缺点是什么?

【问题讨论】:

    标签: java arraylist java-8 iterator java-stream


    【解决方案1】:

    当您调用stream() 时,API 内部调用spliterator(),它类似于iterator()

    对于ArrayList,返回的Spliterator / Iterator 使用expectedModCount 字段与列表的modCount 字段进行比较,以检查列表是否已被修改。

    Iterator的实现在创建迭代器时初始化expectedModCount字段。

    Spliterator 的实现延迟初始化,直到第一个元素取自 Spliterator

    这意味着它允许在对stream() 的调用和对实际开始从流中提取数据的终端操作的调用之间修改列表。

    【讨论】:

    猜你喜欢
    • 2014-06-19
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-17
    • 2017-05-04
    • 1970-01-01
    相关资源
    最近更新 更多