`
gaowei52306
  • 浏览: 25057 次
  • 性别: Icon_minigender_2
  • 来自: 深圳
社区版块
存档分类
最新评论

遍历集合时不要修改集合的理解

    博客分类:
  • java
 
阅读更多
public static void main(String[] args) 
	{
		//创建一个集合
		Collection books = new HashSet();
		books.add("One book");
		books.add("Two book");
		books.add("Three book");
		//获取books集合对应的迭代器
		Iterator it = books.iterator();
		
		try
		{
			while(it.hasNext())
			{
				String book = (String)it.next();
				System.out.println(book);
				//note: 如果删除"Two book",本示例不会引发异常
				if (book.equals("Three book"))
				{
					//使用Iterator迭代过程中,不可修改集合元素!
					books.remove(book);
				}
			}
			System.out.println("移除元素之后:"+books);
		}catch (ConcurrentModificationException e) {
			System.out.println(e);
		}
	}

通过查询源码解释这一现象
     移除"Three book"时
它不是最后一个元素,故在remove时modCount的值增加了。
在循环下一个元素it.next();时,进入如下代码:
if (modCount != expectedModCount)
                throw new ConcurrentModificationException();


由于modCount为4,expectedModCount为3故抛出异常。

    移除"Two book"时
由于它是最后一个元素,虽然在remove时modCount改为4,但是程序不会走it.next();代码了,所以没有抛异常。

为什么修改成以下代码是安全的呢?
if (book.equals("Three book"))
			{
				//使用Iterator迭代过程中,通过它来移除集合元素是安全的
				it.remove();
			}

看看源码就知道了
public void remove() {
            if (current == null)
                throw new IllegalStateException();
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            Object k = current.key;
            current = null;
            HashMap.this.removeEntryForKey(k);
            expectedModCount = modCount;
        }

remove之后它会将modCount的值赋给expectedModCount,也就不会出现抛异常这回事了。由此可见使用Iterator迭代过程中,通过remove();来移除集合元素是安全的
分享到:
评论

相关推荐

    跟我学Java-day15-学员管理系统.pdf

    4.1 定义一个方法,接收ArrayList集合 4.2 方法内遍历集合,将学生信息进行输出 4.3 在查看 所有学生选项里调用查看学生方法 5. 学生管理系统的删除学生功能实现步骤 5.1 定义一个方法,接收ArrayList集合 5.2 ...

    深入理解Java:10个示例展示核心概念和用法涵盖了类和对象、继承和多态、接口和实现、异常处理、集合框架、文件操作、多线程、输入

    5. 集合框架:介绍了使用ArrayList作为动态数组来存储和遍历数据的示例。 6. 文件操作:展示了读取文件内容并打印到控制台的文件操作示例。 7. 多线程:演示了使用多线程并发执行任务的示例。 8. 输入输出:展示了...

    习----题-Java-Web程序设计教程-[共2页].pdf

    public class MyCmp implements Comparator<Student>{ public int compare(Student s1, Student s2){ …… } } 总之,泛型其实是在集合创建时就设定集合中放置何种类型的对象。这样以后读出元素时就 不需要强制转换...

    Visual C#2010 从入门到精通(Visual.C#.2010.Step.By.Step).完整去密码锁定版 I部分

    原书名: Microsoft Visual C# 2010 Step by Step ...28.1.1 用plinq增强遍历集合时的性能 594 28.1.2 指定plinq查询选项 598 28.1.3 取消plinq查询 598 28.2 同步并发的命令式数据访问 599 28.2.1 ...

    AIC的Java课程1-6章

     可以使用迭代器Iterator遍历集合的元素。  [*]理解泛型概念,声明和使用带有范型的集合。 第11章 集合 4课时  理解什么是集合以及Java的集合框架。  辨析List,Set和Map接口...

    深入理解JavaScript系列(35):设计模式之迭代器模式详解

    3.遍历的同时更改迭代器所在的集合结构可能会导致问题(比如C#的foreach里不允许修改item)。 正文 一般的迭代,我们至少要有2个方法,hasNext()和Next(),这样才做做到遍历所有对象,我们先给出一个例子: 代码...

    Jhead (Exif 信息批量命令行编辑工具,win命令行,含源代码)一个直接用命令查看修改删除图片属性Exif信息的文件

    下载jhead时,记得把jhead程序存放在要更改的照片文件夹里,不然无法使用。 它的强大在于它 一、提供了其他工具所不能企及的功能 二、强大的批处理能力 唯一的问题是:jhead不是个window程式,它是个DOS程式,许多用...

    java解析xml及4种常用解析比较

    首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。 2)SAX SAX处理的优点非常...

    hibernate 框架详解

    可滚动遍历(Scrollable iteration) 11.4.1.7. 外置命名查询(Externalizing named queries) 11.4.2. 过滤集合 11.4.3. 条件查询(Criteria queries) 11.4.4. 使用原生SQL的查询 11.5. 修改持久对象 11.6. ...

    hibernate3.04中文文档.chm

    20.5. 理解集合性能(Understanding Collection performance) 20.5.1. 分类(Taxonomy) 20.5.2. Lists, maps 和sets用于更新效率最高 20.5.3. Bag和list是反向集合类中效率最高的 20.5.4. 一次性删除(One...

    Hibernate教程

    20.5. 理解集合性能(Understanding Collection performance) 20.5.1. 分类(Taxonomy) 20.5.2. Lists, maps 和sets用于更新效率最高 20.5.3. Bag和list是反向集合类中效率最高的 20.5.4. 一次性删除(One ...

    最全Hibernate 参考文档

    19.5. 理解集合性能(Understanding Collection performance) 19.5.1. 分类(Taxonomy) 19.5.2. Lists, maps 和sets用于更新效率最高 19.5.3. Bag和list是反向集合类中效率最高的 19.5.4. 一次性删除(One ...

    Hibernate参考文档

    19.5. 理解集合性能(Understanding Collection performance) 19.5.1. 分类(Taxonomy) 19.5.2. Lists, maps 和sets用于更新效率最高 19.5.3. Bag和list是反向集合类中效率最高的 19.5.4. 一次性删除(One ...

    Hibernate3+中文参考文档

    19.5. 理解集合性能(Understanding Collection performance) 19.5.1. 分类(Taxonomy) 19.5.2. Lists, maps 和sets用于更新效率最高 19.5.3. Bag和list是反向集合类中效率最高的 19.5.4. 一次性删除(One ...

    Java2核心技术.part5

    4.2.3更改器方法与访问器方法 4.3用户自定义类 4.3.1一个Employee类 4.3.2多个源文件的使用 4.3.3解析Employee类 4.3.4从构造器开始 5.2.2相等测试与继承 5.2.3 hashCode方法 5.2.4 ...

    Java2核心技术.part3

    4.2.3更改器方法与访问器方法 4.3用户自定义类 4.3.1一个Employee类 4.3.2多个源文件的使用 4.3.3解析Employee类 4.3.4从构造器开始 5.2.2相等测试与继承 5.2.3 hashCode方法 5.2.4 ...

    Java2核心技术.part1

    4.2.3更改器方法与访问器方法 4.3用户自定义类 4.3.1一个Employee类 4.3.2多个源文件的使用 4.3.3解析Employee类 4.3.4从构造器开始 5.2.2相等测试与继承 5.2.3 hashCode方法 5.2.4 toString方法 ...

    Java2核心技术.part6

    4.2.3更改器方法与访问器方法 4.3用户自定义类 4.3.1一个Employee类 4.3.2多个源文件的使用 4.3.3解析Employee类 4.3.4从构造器开始 5.2.2相等测试与继承 5.2.3 hashCode方法 5.2.4 ...

    Java2核心技术.part4

    4.2.3更改器方法与访问器方法 4.3用户自定义类 4.3.1一个Employee类 4.3.2多个源文件的使用 4.3.3解析Employee类 4.3.4从构造器开始 5.2.2相等测试与继承 5.2.3 hashCode方法 5.2.4 ...

    Java2核心技术.part2

    4.2.3更改器方法与访问器方法 4.3用户自定义类 4.3.1一个Employee类 4.3.2多个源文件的使用 4.3.3解析Employee类 4.3.4从构造器开始 5.2.2相等测试与继承 5.2.3 hashCode方法 5.2.4 ...

Global site tag (gtag.js) - Google Analytics