`
zhongkem
  • 浏览: 152538 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

从集合类中删除元素时容易碰到的问题(ConcurrentModificationException)

阅读更多

先看下面的一段代码,也许很多人都会觉得没任何问题:

  Set<String> myset= new HashSet<String>();
    myset.add("apple");
    myset.add("orange");
    Iterator it = myset.iterator();
    while(it.hasNext()) {
        String fruit=(String) it.next();
       if(fruit.equals("apple")) 
          myset.remove(fruit);    //wrong
    }

 

 但实际运行中会抛ConcurrentModificationException异常。。从网上搜了下,摘抄如下:

当使用 fail-fast iterator 对 Collection 或 Map 进行迭代操作过程中尝试直接修改 Collection / Map 的内容时,即使是在单线程下运行,   java.util.ConcurrentModificationException 异常也将被抛出。

  Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。

  所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。

  有意思的是如果你的 Collection / Map 对象实际只有一个元素的时候, ConcurrentModificationException 异常并不会被抛出。这也就是为什么在 javadoc 里面指出: it would be wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs.

    因此,想让上面的代码正常运行,可以采用下面的方式:

  Set<String> myset= new HashSet<String>();
    myset.add("apple");
    myset.add("orange");
    Iterator it = myset.iterator();
    while(it.hasNext()) {
        String fruit=(String) it.next();
       if(fruit.equals("apple")) 
          it.remove();    //right
    }

 

这种问题应该特别注意。我以前就没注意过。。今天刚了解。。。以前写的代码不得不回去改!!!

 

分享到:
评论

相关推荐

    遍历并批量删除容器中元素出现ConcurrentModificationException原因及处置

    当你在一个迭代器正在遍历集合的过程中添加或删除元素时,就会抛出这个异常。这个问题在单线程环境下不会出现,但在多线程并发场景下,如果多个线程同时修改一个集合,就可能导致`ConcurrentModificationException`...

    java.util.ConcurrentModificationException 异常问题详解1

    这个示例代码尝试在遍历 ArrayList 时删除其中的一个元素,这将导致 ConcurrentModificationException 异常。 那么,为什么会抛出这个异常呢?我们可以通过查看 ArrayList 的源码来了解原因。ArrayList 的 iterator...

    使用Iterator接口遍历集合元素

    hasNext() 方法用于判断集合中是否还有未被遍历的元素,next() 方法用于返回集合中的下一个元素,remove() 方法用于删除集合中的上一个元素。 Iterator 接口主要用于遍历集合元素,而不是提供盛装对象的能力。因此...

    在list集合中输入元素,去除重复的元素并输出

    根据给定文件的信息,本文将详细介绍如何在Java的List集合中去除重复元素的三种方法:使用for循环、使用迭代器以及利用HashSet的特性。 ### 一、使用for循环去除重复元素 这种方法的基本思想是通过双重循环来遍历...

    多线程中使用Java集合类.doc

    在多线程环境中,使用Java集合类需要注意线程安全问题,因为不同的线程可能会同时访问和修改集合,导致数据不一致或引发异常。本篇主要讨论在并发编程中使用Java集合类的一些关键知识点。 首先,Java集合框架中的大...

    集合类框架专题

    Java集合类框架是Java编程语言中用于存储和管理对象的重要工具。这个框架提供了一组接口和实现这些接口的类,使得开发者可以高效地处理数据集合。我们首先来看一下主要的接口和它们的特点: 1. **Collection接口**...

    java集合类遍历的同时如何进行删除操作.docx

    在Java编程中,集合类遍历的同时进行删除操作是一个常见的需求,但如果不正确地执行,可能会导致`ConcurrentModificationException`。这个问题主要出现在迭代器正在遍历集合时,集合本身被修改的情况。以下是对这个...

    (完整版)Java集合类.ppt

    Java集合类是Java编程语言中用于存储和管理对象的重要工具。这个完整的版本涵盖了Java集合框架的核心概念,包括集合类概述、Collection接口、List接口、Set接口以及Map接口,还有迭代器Iterator的使用。 集合类概述...

    java集合类的全解

    此外,还可以通过 `remove()` 方法从集合中移除当前元素。 - **泛型**:在Java集合中广泛使用泛型来提高代码的安全性和可读性。通过指定集合中的元素类型,可以避免运行时类型转换错误。 #### 五、总结 Java集合...

    Java集合类面试题.docx

    面试时,面试官经常通过提问关于集合类的问题来评估候选人的基础知识和实际经验。以下是一些常见的Java集合类面试题及其详细解答: 1. **Java集合框架是什么?** Java集合框架是一组接口和类,为在Java中处理对象...

    java集合类面试题总结

    下面总结了 Java 集合类的一些常见问题和答案。 HashMap 和 Hashtable 的区别 HashMap 和 Hashtable 都是 Java 中的散列表实现,但它们有所不同。HashMap 允许一个 null 键和多个 null 值,而 Hashtable 不允许 ...

    细说Java之常用集合类

    - 使用`Vector`创建的`Iterator`,如果在迭代期间有其他线程修改了`Vector`,那么调用`Iterator`的方法时可能会抛出`ConcurrentModificationException`。 4. **Stack** - `Stack`继承自`Vector`,它是一个后进先...

    JAVA基础-集合类

    在迭代过程中需要注意的是,如果在迭代过程中尝试修改集合(如删除元素),可能会导致`ConcurrentModificationException`异常。为了避免这种情况,应该使用迭代器的`remove()`方法来移除元素。 #### 三、Set详解 #...

    实现Java删除一个集合的多个元素

    在尝试使用`for each`循环遍历并删除`source`集合中某些元素时,程序抛出了`ConcurrentModificationException`。这是因为Java的`for each`循环实际上是基于`Iterator`的。当使用`Iterator`遍历集合时,Java不允许...

    删除JAVA集合中元素的实现代码

    在删除集合中的元素时,我们需要注意避免 ConcurrentModificationException 异常的出现。因为集合是在循环中的时候是不可以删除它的元素的。如果我们尝试删除集合中的元素,会抛出 ConcurrentModificationException ...

    java 集合并发操作出现的异常ConcurrentModificationException

    在Java编程中,`ConcurrentModificationException`是一个常见的运行时异常,主要出现在多线程环境下对集合类(如List、Set、Map等)进行并发修改时。然而,这个异常不仅限于多线程环境,即使在单线程中,如果在遍历...

    forEach中为什么不能删除元素解决方案.pdf

    然而,在使用`forEach`循环时,直接尝试修改遍历的集合(例如删除或添加元素)是不被允许的,因为这会导致`ConcurrentModificationException`异常。本文将探讨在使用`forEach`循环中遇到无法删除元素的问题,并提供...

    出现java.util.ConcurrentModificationException 问题及解决办法

    在Java编程中,`java.util.ConcurrentModificationException` 是一个常见的运行时异常,通常发生在尝试并发修改集合时。这个异常的产生是由于集合类(如HashMap)的非线程安全特性,当你在一个线程中使用迭代器遍历...

    Java集合使用 Iterator 删除元素

    Java集合使用Iterator删除元素是Java编程中的一种常见操作。Iterator是Java集合框架中的一种接口,用于遍历集合中的元素。在使用Iterator遍历集合时,如果需要删除某些元素,就需要使用Iterator的remove方法,而不能...

    collecter集合总结

    需要注意的是,在迭代的过程中不能对集合中元素进行修改,否则将产生 java.util.ConcurrentModificationException。 选择集合 在实际开发中,选择合适的集合是非常重要的。以下是一些选择集合的建议: * 如果需要...

Global site tag (gtag.js) - Google Analytics