集合 - 迭代器.remove() vs 集合.remove()

13

根据Sun公司的说法:

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

我有两个问题:

  1. 这个操作中“Iterator.remove()”与其他操作相比有什么特殊的稳定性?
  2. 如果在大多数使用情况下都没有用,他们为什么会提供一个“Collection.remove()”方法?
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 的过程中调用了 l.remove(),所以此代码无效。

以下是正确的写法:

    Iterator<Integer> it = l.iterator();
    while (it.hasNext()) {
        int el = it.next();
        if (el < 3) {
            it.remove();
        }
    }

我在 l.remove(e1) 后面加了一个 break 指令,使用 Java 1.6,虚拟机没有抛出异常。 - TomasMolina

9

如果正在对一个集合进行迭代并使用:

Collection.remove() 

当你在改变用于构造完成循环所需的明确调用序列的对象状态时,可能会遇到运行时错误(特别是ConcurrentModificationException)。

如果你使用:

Iterator.remove()

你告诉运行时,你想要改变底层集合并重新评估完成循环所必需的显式调用序列。


8
正如你引用的文档明确说明的那样,

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


(强调添加)

在使用迭代器时,除了调用 Iterator.remove() 外,不能修改集合。

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

3
这个操作为什么比其他操作更加稳定呢?这意味着迭代器知道你已经删除了元素,因此它不会产生ConcurrentModificationException异常。
如果在大多数情况下它不会有用,为什么他们提供了"Collection.remove()"方法呢?通常,您会使用Map.remove()或Collection.remove(),因为这可能比遍历每个对象更有效。如果您经常在迭代时进行删除操作,我认为您应该使用不同的集合。

0
据我所知,Collection.remove(int index)方法将返回被移除的对象。而Iterative.remove()则不会返回。

0
  1. 这只是一种设计选择。可以指定不同的行为(即迭代器必须跳过由 Collection.remove() 移除的值),但那样会使集合框架的实现更加复杂。因此,选择未指定。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接