代码之家  ›  专栏  ›  技术社区  ›  Peter Smit

Java集合迭代器,用于移除元素安全吗?

  •  8
  • Peter Smit  · 技术社区  · 14 年前

    我想迭代一个集合,并从集合中删除符合某些条件的元素。这个 documentation of iterator 在遍历列表时,对修改列表什么也不说。

    这有可能吗?如果没有,最好的方法是什么?注意,我只想从迭代器提供的集合中删除元素。

    编辑 :很快就证明了这是可能的。我也可以用下面的语法来做吗?

    for(Node n : mySet) {
        mySet.remove(n);
    }
    
    5 回复  |  直到 9 年前
        1
  •  16
  •   tangens    14 年前

    是的,可以使用迭代器安全地删除当前元素:

    iterator.remove();
    

    这个 javadoc 属于 remove() 说:

    如果指定元素存在,则从该集合中移除该元素(可选操作)。更正式地说,删除元素e,以便(o==null?e==null:o.equals(e)),如果这个集合包含这样一个元素。如果此集合包含元素,则返回“真”(如果此集合因调用而更改,则返回“等效”)。(调用返回后,此集合将不包含元素。)


    回答您的下一个问题:不,您不能。在使用增强的for循环迭代集时修改该集将导致 ConcurrentModificationException .

        2
  •  1
  •   vodkhang    14 年前

    切线的答案是正确的。如果不使用iterator.remove()但直接从set中移除,则将收到异常调用 ConcurrentModificationException

        3
  •  1
  •   mindas    9 年前

    这实际上在Java 8中得到了改进。现在你可以

    mySet.removeIf(element -> someConditionMatches());

    以上是作为一个 default 方法 java.util.Collection 而且应该避免每个人写无聊的循环。也就是说,它应该适用于任何类型的收集,而不仅仅是 Set .

        4
  •  0
  •   user85155    14 年前

    这是.remove()的作用:

    http://download.oracle.com/javase/6/docs/api/java/util/Iterator.html#remove%28%29

    “从基础集合中移除迭代器返回的最后一个元素(可选操作)。每次调用Next只能调用此方法一次。如果在迭代过程中以除调用此方法以外的任何方式修改基础集合,则未指定迭代器的行为。”

        5
  •  -1
  •   DerMike Vladimír Schäfer    14 年前

    对于(节点n:myset){ myset.remove(n);

    无法工作,因为您正在修改正在迭代的集。但是,这只能使用迭代器来完成,而不是这样。

    这是使用增强for循环的一个缺点。