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();来移除集合元素是安全的
分享到:
相关推荐
迭代器模式是一种行为设计模式,主要目的是在不暴露集合内部结构的情况下,允许外部代码遍历集合的所有元素。这种模式将遍历操作从集合类中分离出来,实现了数据结构和遍历机制的解耦。在大多数编程语言中,迭代器...
LinkedList则是基于双向链表实现的List,它的增删操作(尤其是首尾操作)效率高,但在随机访问时性能较差,因为需要从头或尾部开始遍历。LinkedList的`add()`方法在链表的任何位置插入元素都只需修改相邻节点的引用...
Java中的集合遍历是编程实践中常见的操作,不同的遍历方式有着不同的实现原理、性能特点以及适用场景。...总之,理解Java中各种遍历集合的方法及其原理,可以帮助开发者更高效、安全地处理数据集合,提高代码质量。
本文将详细介绍Java中遍历集合的三种常见方式,并通过实例进行对比分析。 ### 方式一:转化为数组后遍历 这种方式首先将集合(如List)转化为数组,然后通过数组的for-each循环进行遍历。代码如下: ```java ...
在本实例中,我们将深入探讨如何使用`foreach`循环遍历集合元素,并理解其工作原理以及可能遇到的问题。 首先,让我们看下给出的代码示例: ```java import java.util.*; public class ForeachTest { public ...
在C#编程中,List<T> 是一个常用的集合类,用于存储同类型的对象数组...希望以上内容对你的C#程序设计有所帮助,理解并掌握正确的遍历和删除技巧是优化代码效率的关键。在实际开发中,应根据具体需求选择最适合的方法。
在Java中,常见的遍历集合的方法包括传统的for循环、迭代器Iterator以及foreach循环。 1. 传统的for循环遍历 这种方式需要开发者手动维护一个计数器,并通过调用`size()`方法获取集合长度,然后通过`get(index)`...
Thymeleaf提供了迭代器`th:each`来遍历集合。以下是一个展示`commanders`列表的HTML表格示例: ```html <!DOCTYPE html> <title>Commanders List 编号 姓名 年龄 ${commanders}"> ${...
在这个"js实例之集合遍历字符创修改"的主题中,我们将深入探讨如何使用JavaScript有效地遍历数组、对象集合以及如何对字符串进行修改。 首先,让我们从集合遍历开始。在JavaScript中,集合可以是数组或对象。数组的...
这个问题主要出现在迭代器正在遍历集合时,集合本身被修改的情况。以下是对这个主题的详细说明: 1. **背景**: 当我们尝试在循环遍历集合(如ArrayList)时删除元素,Java的默认行为是不允许的,因为这违反了迭代...
- 在多线程环境下,不要在遍历过程中修改HashMap,否则可能会抛出`ConcurrentModificationException`。如果需要在遍历中修改,可以使用`Iterator.remove()`方法,或者使用`CopyOnWriteArrayMap`等线程安全的集合。 -...
C#中的`foreach`遍历是编程中常用的操作,它简化了对...总之,C#的`foreach`循环提供了简洁、易读的代码来遍历集合和数组,是日常编程中不可或缺的工具。理解其工作原理和注意事项,有助于编写更加高效和可靠的代码。
因此,在遍历的同时不要修改`Map`。 - 使用流API遍历时,虽然代码更简洁,但性能上可能不如传统的迭代器或增强型for循环,尤其是在处理大量数据时。 - `keySet()`方法返回的是键的集合视图,这意味着对返回的`Set`...
在ASP.NET后端开发中,Cookie是用于存储用户特定信息的一种小型文本文件...正确理解和使用Cookies集合,可以提高应用程序的功能性和用户体验。通过了解和实践上述方法,你将能够更有效地处理与Cookies相关的各种问题。
### 数据结构与算法详解——遍历列表集合 #### 1. 数据结构与算法基础 ##### 1.1 数据结构的作用 - **定义**: 数据结构是计算机科学中的一个重要概念,它涉及如何组织和存储数据,以便有效地进行管理和操作。 - *...
- 修改数组:在foreach循环中,如果尝试修改数组元素,可能会导致编译错误,因为foreach循环不支持在迭代过程中修改集合。如需修改,建议使用for循环。 通过了解和掌握这些基本的数组遍历方法,你将能更好地利用C#...
Java 5引入了增强型for循环,也称为foreach循环,使得遍历集合更加简洁。对于List集合,其使用方式如下: ```java for (String data : list) { // 处理data } ``` 这种方式内部实际上是调用了迭代器实现,...
例如,我们可以使用map和forEach方法来遍历集合: ```java list.stream().forEach(System.out::println); map.forEach((key, value) -> System.out.println("Key: " + key + ", Value: " + value)); ``` 总结,...
- 提供修改特定学生某项分数的功能,通过遍历集合,找到对应学生后根据输入修改分数。 这个练习旨在帮助学习者理解Java集合框架的基本用法,包括集合的创建、操作、遍历以及对象的创建和操作。通过这个练习,可以...