`
leonzhx
  • 浏览: 799801 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

    博客分类:
  • Java
 
阅读更多

今天在遍历一个Map时,需要删除Map中的某些元素,但出现了ConcurrentModificationException,上网查了下,原来是迭代器Iterator的问题。

下面用代码具体说明下:

 

import java.util.HashMap;  
import java.util.Iterator;  
import java.util.Map;  
import java.util.Set;  
 
 
public class MapDeleteTest {  
    public static void main(String[] args) {  
        Map<Integer,String> m = new HashMap<Integer,String>();  
        //往map中加入测试数据  
        for(int i=1;i<6;i++) {  
            m.put(i, "value" + i);  
        }  
        //对m进行遍历,并删除key为2的项  
        Set<Map.Entry<Integer,String>> entrys = m.entrySet();  
        //第一种方法  
        for(Iterator<Map.Entry<Integer,String>> i = entrys.iterator();i.hasNext();) {  
                Map.Entry<Integer,String> entry = i.next();  
                System.out.println("key=" + entry.getKey() + "   value=" + entry.getValue());  
                if(entry.getKey()==2) {  
                    m.remove(entry.getKey());  
                }  
            }  
        //第二种方法  
        for(Map.Entry<Integer,String> entry : entrys) {  
            System.out.println("key=" + entry.getKey() + "   value=" + entry.getValue());  
            if((Integer)entry.getKey()==2) {  
                m.remove(entry.getKey());  
            }  
        }  
        //第三种方法  
        for(Iterator i = entrys.iterator();i.hasNext();) {  
            Map.Entry entry = (Map.Entry)i.next();  
            System.out.println("key=" + entry.getKey() + "   value=" + entry.getValue());  
            if((Integer)entry.getKey()==2) {  
                i.remove();  
            }  
        }  
    }     
}

代码的要求就是删除Map中key为2的项。

而在三种方法中,前两种都会抛出异常,只有第三种能正常执行。

原因:

"当使用 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是List,那么用简单的for循环也能正常执行【for(int i=0; i<list.size();i++ )】,因为它不依赖于Iterator。

另外对于Iterator要注意的是,一次Next后,只能执行一次remove。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/MageShuai/archive/2009/10/20/4703255.aspx

分享到:
评论

相关推荐

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

    标题中提到的“遍历并批量删除容器中元素”是引发此异常的一个典型操作。在Java中,我们通常会使用`Iterator`来安全地遍历并修改集合,因为`Iterator`提供了`remove()`方法来删除当前迭代的元素。但如果你在不使用`...

    HashMap和List遍历方法及如何遍历删除元素总结

    HashMap和List遍历方法及如何遍历删除元素总结 HashMap和List都是Java中最常用的数据结构,它们都可以用来存储和操作数据。然而,在遍历和删除元素时,需要小心地处理,以免出现问题。下面总结了HashMap和List的...

    正确遍历删除List中的元素方法(推荐)

    在Java编程中,遍历并删除List中的元素是一项常见的操作,但如果不小心处理,可能会遇到错误,如`ConcurrentModificationException`。以下是几种常见的遍历删除List元素的方法及其注意事项: 1. **通过增强的for...

    java中循环遍历删除List和Set集合中元素的方法(推荐)

    在Java编程中,遍历并删除集合(如List或Set)中的元素是一项常见的操作,但如果不正确地执行,可能会导致`ConcurrentModificationException`异常。这个异常通常在尝试修改正在迭代的集合时出现,因为Java的集合迭代...

    Java HashMap 如何正确遍历并删除元素的方法小结

    这段代码将抛出 `java.util.ConcurrentModificationException` 异常,因为在遍历 HashMap 的元素过程中删除了当前所在元素,下一个待访问的元素的指针也由此丢失了。 2. 正确的删除方法 正确的删除方法是使用迭代...

    使用Iterator接口遍历集合元素

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

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

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

    java哈希遍历_哈希遍历_

    - 在多线程环境下,不要在遍历过程中修改HashMap,否则可能会抛出`ConcurrentModificationException`。如果需要在遍历中修改,可以使用`Iterator.remove()`方法,或者使用`CopyOnWriteArrayMap`等线程安全的集合。 -...

    Iterator遍历过程中list删除导致异常

    当你想在迭代过程中删除元素时,应该使用`Iterator`的`remove()`方法,而不是直接调用集合的`remove()`方法。这样,`Iterator`会正确处理集合的内部状态,避免异常: ```java List&lt;String&gt; list = new ArrayList...

    java-遍历map

    - 在遍历`Map`时,如果在遍历过程中尝试修改`Map`(例如添加或删除元素),可能会引发`ConcurrentModificationException`异常。因此,在遍历的同时不要修改`Map`。 - 使用流API遍历时,虽然代码更简洁,但性能上可能...

    Java如何在List或Map遍历过程中删除元素

    在Java编程中,遍历并删除List或Map中的元素是一个常见的任务,但如果不理解其内部机制,可能会导致一些未预期的问题。本文将深入探讨在Java中如何安全地在List和Map遍历过程中删除元素。 首先,我们来看List的遍历...

    java中List对象集合的遍历方法(三个)

    如果在遍历过程中需要移除元素,必须使用`it.remove()`,直接调用`list.remove()`会导致并发修改异常(ConcurrentModificationException)。 ### 第二种:增强型for循环(foreach) ```java for (A a : list) { /...

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

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

    Java中遍历ConcurrentHashMap的四种方式详解

    使用Iterator遍历ConcurrentHashMap可以避免ConcurrentModificationException的出现。这种方式的优点是可以安全地遍历Map的内容,并且可以在遍历过程中修改Map的内容。但是,需要注意的是,使用Iterator遍历需要手动...

    【Java面试题】List如何一边遍历,一边删除?

    在Java编程中,遍历并删除List集合是一个常见的操作,但在实际编程中,如果不使用正确的方法,可能会导致`java.util.ConcurrentModificationException`异常。本文主要针对这个面试题,详细讲解如何在遍历List的同时...

    各容器与迭代器的用法.docx

    容器是用来存储和管理对象的集合类,而迭代器则是用来遍历和访问容器中元素的接口。本篇将详细介绍几种常见的容器类(如LinkedList、Vector、ArrayList和Hashtable)以及它们的迭代器用法。 1. **LinkedList**: ...

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

    这种方法通过迭代器(Iterator)来遍历列表,并在遍历过程中删除重复的元素。这种方式可以有效地避免`ConcurrentModificationException`异常。 ```java Iterator&lt;Integer&gt; iterator = list.iterator(); while ...

    Java list利用遍历进行删除操作3种方法解析

    这个示例中,会出现下标问题,因为在删除元素后,list 的大小发生了变化,导致下标的计算不正确。为了解决这个问题,可以使用倒序操作,避免下标问题: ```java int size = list.size(); for (int i = size - 1; i ...

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

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

    java 使用foreach遍历集合元素的实例

    在Java编程语言中,`foreach`循环是一种简洁的遍历集合元素的方式,它引入自Java 5(JDK 1.5)。`foreach`循环也被称为增强for循环,它的主要目的是简化对数组和集合的迭代操作。在本实例中,我们将深入探讨如何使用...

Global site tag (gtag.js) - Google Analytics