11

据孙,

“Iterator.remove 是在迭代期间修改集合的唯一安全方法;如果在迭代过程中以任何其他方式修改底层集合,则行为未指定。”

我有两个问题:

  1. 是什么让这个操作“Iterator.remove()”比其他操作更稳定?
  2. 如果“Collection.remove()”方法在大多数用例中都没有用,为什么还要提供它?
4

6 回答 6

16

首先,Collection.remove()非常好用。它适用于很多用例,可能比Iterator.remove().

但是,后者解决了一个特定问题:它允许您在迭代集合时修改集合。

解决的问题Iterator.remove()如下图所示:

    List<Integer> l = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4));
    for (int el : l) {
        if (el < 3) {
            l.remove(el);
        }
    }

此代码无效,因为l.remove()在迭代过程中调用了 over l

下面是正确的写法:

    Iterator<Integer> it = l.iterator();
    while (it.hasNext()) {
        int el = it.next();
        if (el < 3) {
            it.remove();
        }
    }
于 2013-01-07T17:00:19.220 回答
9

如果您正在迭代集合并使用:

Collection.remove() 

您可能会收到运行时错误(特别是 ConcurrentModifcationException),因为您正在更改先前用于构造完成循环所需的显式调用系列的对象的状态。

如果您使用:

Iterator.remove()

您告诉运行时您想要更改基础集合并重新评估完成循环所需的显式调用系列。

于 2013-01-07T17:02:46.337 回答
8

正如您引用的文档明确指出的那样,

Iterator.remove 是在迭代期间修改集合的唯一安全方法

(重点补充)

使用 am 迭代器时,您不能修改集合,除非通过调用Iterator.remove().

如果您不迭代集合,您将使用Collection.remove().

于 2013-01-07T16:59:38.407 回答
2

是什么让这个操作“Iterator.remove()”比其他操作更稳定?

这意味着迭代器知道您删除了该元素,因此它不会产生 ConcurrentModifcationException。

如果“Collection.remove()”方法在大多数用例中都没有用,为什么还要提供它?

通常你会使用 Map.remove() 或 Collection.remove() 因为这比遍历每个对象更有效。如果您在经常迭代时删除,我怀疑您应该使用不同的集合。

于 2013-01-07T17:02:15.527 回答
0
  1. 只是一种设计选择。可以指定不同的行为(即迭代器必须跳过由 Collection.remove() 删除的值),但这会使集合框架的实现更加复杂。所以选择不指定它。

  2. 它非常有用。如果您知道要删除的对象,为什么要迭代?

于 2013-01-07T17:04:06.280 回答
0

据我了解, Collection.remove(int index) 也将返回已删除的对象。Iterative.remove() 不会。

于 2017-01-11T05:48:44.733 回答