Java 集合框架之 ConcurrentModificationException

1、迭代器原理

        java 中提供了很多的集合类,不同集合类的数据结构不同,所以这些集合类的数据存储方式和遍历方式也应该不同,所以无法为所有集合类提供统一迭代器,只能提供一个接口。

       通过源码分析可以得知,集合对接口的实现在他们的具体实现类中,并且以私有内部类的方式体现。

2、ConcurrentModificationException

public class ConcurrentModificationExceptionDemo
{
	public static void main(String[] args)
	{
		Collection<String> c = new ArrayList<String>();
		c.add("Java");
		c.add("Android");
		c.add("HTML");
		c.add("C#");
		
                // 迭代器遍历集合
		Iterator<String> it = c.iterator();
		
		while(it.hasNext())
		{
			String str = it.next();
			
			if(str.equals("Java"))
			{
                                // 集合 add() 方法添加元素
				c.add("JavaEE");
			}
		}
	}
}

       在运行以上代码时,程序将会抛出 ConcurrentModificationException 异常(并发操作异常),这是因为代码中使用迭代器遍历集合过程中通过集合添加了元素

   (1) 概述

       当检测到对象的并发修改,但不允许这种修改时抛出该异常

   (2) 产生原因

       迭代器依赖于集合存在,在迭代时通过集合添加元素,但集合的改变并没有同步到迭代器,所以引发该异常。

   (3) 解决方法

       方式一:使用迭代器遍历,通过迭代器来修改元素(只使用于 List 实现类

public class ConcurrentModificationExceptionDemo
{
	public static void main(String[] args)
	{
		List<String> c = new ArrayList<String>();
		c.add("Java");
		c.add("Android");
		c.add("HTML");
		c.add("C#");
		
                // 使用迭代器遍历集合
		ListIterator<String> it = c.listIterator();
		
		while(it.hasNext())
		{
			String str = it.next();
			
			if(str.equals("Java"))
			{
				// 使用迭代器的 add() 添加元素
				it.add("JavaEE");
			}
		}
		
		System.out.println(c);
	}
}

       运行结果:

       方式二: 使用集合遍历,通过集合来修改元素

public class ConcurrentModificationExceptionDemo
{
	public static void main(String[] args)
	{
		List<String> c = new ArrayList<String>();
		c.add("Java");
		c.add("Android");
		c.add("HTML");
		c.add("C#");
		
		// 使用集合遍历
		for(int i = 0; i < c.size(); i++)
		{
			String str = c.get(i);
			
			if(str.equals("Java"))
			{
				// 使用集合 add() 方法添加元素
				c.add("JavaEE");
			}
		}
		
		System.out.println(c);
	}
}

        运行结果:

        注意:

        foreach 遍历其底层为迭代器,所以遍历时修改也会出现该异常。

        两种方式虽然都满足了需求,但是存在一些不同之处:方式一插入新元素的位置在当前迭代位置的后面;而方式二插入新元素的位置在列表最后面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值