`
gaowei52306
  • 浏览: 25679 次
  • 性别: 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();来移除集合元素是安全的
分享到:
评论

相关推荐

    65丨迭代器模式(上):相比直接遍历集合数据,使用迭代器有哪些优势?1

    迭代器模式是一种行为设计模式,主要目的是在不暴露集合内部结构的情况下,允许外部代码遍历集合的所有元素。这种模式将遍历操作从集合类中分离出来,实现了数据结构和遍历机制的解耦。在大多数编程语言中,迭代器...

    list遍历集合源码

    LinkedList则是基于双向链表实现的List,它的增删操作(尤其是首尾操作)效率高,但在随机访问时性能较差,因为需要从头或尾部开始遍历。LinkedList的`add()`方法在链表的任何位置插入元素都只需修改相邻节点的引用...

    Java遍历集合方法分析(实现原理、算法性能、适用场合)_.docx

    Java中的集合遍历是编程实践中常见的操作,不同的遍历方式有着不同的实现原理、性能特点以及适用场景。...总之,理解Java中各种遍历集合的方法及其原理,可以帮助开发者更高效、安全地处理数据集合,提高代码质量。

    Java遍历集合的三种方式

    本文将详细介绍Java中遍历集合的三种常见方式,并通过实例进行对比分析。 ### 方式一:转化为数组后遍历 这种方式首先将集合(如List)转化为数组,然后通过数组的for-each循环进行遍历。代码如下: ```java ...

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

    在本实例中,我们将深入探讨如何使用`foreach`循环遍历集合元素,并理解其工作原理以及可能遇到的问题。 首先,让我们看下给出的代码示例: ```java import java.util.*; public class ForeachTest { public ...

    C#遍历List并删除某个元素的方法

    在C#编程中,List<T> 是一个常用的集合类,用于存储同类型的对象数组...希望以上内容对你的C#程序设计有所帮助,理解并掌握正确的遍历和删除技巧是优化代码效率的关键。在实际开发中,应根据具体需求选择最适合的方法。

    Java遍历集合方法分析(实现原理、算法性能、适用场合)

    在Java中,常见的遍历集合的方法包括传统的for循环、迭代器Iterator以及foreach循环。 1. 传统的for循环遍历 这种方式需要开发者手动维护一个计数器,并通过调用`size()`方法获取集合长度,然后通过`get(index)`...

    thymeleaf循环遍历集合并呈现在表格中

    Thymeleaf提供了迭代器`th:each`来遍历集合。以下是一个展示`commanders`列表的HTML表格示例: ```html <!DOCTYPE html> <title>Commanders List 编号 姓名 年龄 ${commanders}"> ${...

    js实例之集合遍历字符创修改

    在这个"js实例之集合遍历字符创修改"的主题中,我们将深入探讨如何使用JavaScript有效地遍历数组、对象集合以及如何对字符串进行修改。 首先,让我们从集合遍历开始。在JavaScript中,集合可以是数组或对象。数组的...

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

    这个问题主要出现在迭代器正在遍历集合时,集合本身被修改的情况。以下是对这个主题的详细说明: 1. **背景**: 当我们尝试在循环遍历集合(如ArrayList)时删除元素,Java的默认行为是不允许的,因为这违反了迭代...

    java哈希遍历_哈希遍历_

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

    深入理解C#中foreach遍历的使用方法

    C#中的`foreach`遍历是编程中常用的操作,它简化了对...总之,C#的`foreach`循环提供了简洁、易读的代码来遍历集合和数组,是日常编程中不可或缺的工具。理解其工作原理和注意事项,有助于编写更加高效和可靠的代码。

    java-遍历map

    因此,在遍历的同时不要修改`Map`。 - 使用流API遍历时,虽然代码更简洁,但性能上可能不如传统的迭代器或增强型for循环,尤其是在处理大量数据时。 - `keySet()`方法返回的是键的集合视图,这意味着对返回的`Set`...

    ASP技术常遇问题解答-如何遍历Cookies集合?.zip

    在ASP.NET后端开发中,Cookie是用于存储用户特定信息的一种小型文本文件...正确理解和使用Cookies集合,可以提高应用程序的功能性和用户体验。通过了解和实践上述方法,你将能够更有效地处理与Cookies相关的各种问题。

    遍历列表集合:数据结构与算法详解.md

    ### 数据结构与算法详解——遍历列表集合 #### 1. 数据结构与算法基础 ##### 1.1 数据结构的作用 - **定义**: 数据结构是计算机科学中的一个重要概念,它涉及如何组织和存储数据,以便有效地进行管理和操作。 - *...

    C#数组遍历

    - 修改数组:在foreach循环中,如果尝试修改数组元素,可能会导致编译错误,因为foreach循环不支持在迭代过程中修改集合。如需修改,建议使用for循环。 通过了解和掌握这些基本的数组遍历方法,你将能更好地利用C#...

    Java中List集合的遍历实例详解

    Java 5引入了增强型for循环,也称为foreach循环,使得遍历集合更加简洁。对于List集合,其使用方式如下: ```java for (String data : list) { // 处理data } ``` 这种方式内部实际上是调用了迭代器实现,...

    Java 实例 - 集合遍历源代码-详细教程.zip

    例如,我们可以使用map和forEach方法来遍历集合: ```java list.stream().forEach(System.out::println); map.forEach((key, value) -> System.out.println("Key: " + key + ", Value: " + value)); ``` 总结,...

    Collection集合基本练习1

    - 提供修改特定学生某项分数的功能,通过遍历集合,找到对应学生后根据输入修改分数。 这个练习旨在帮助学习者理解Java集合框架的基本用法,包括集合的创建、操作、遍历以及对象的创建和操作。通过这个练习,可以...

Global site tag (gtag.js) - Google Analytics