Java深入理解 - 迭代器 Iterator 总结
来源:互联网 发布:网络浙江卫视在线直播 编辑:程序博客网 时间:2024/05/22 16:52
今天一位朋友在用迭代器时很郁闷为什么会会报Java.util.ConcurrentModificationExceptiond 异常, 于是写下这篇博客,想详细的讲讲Java里面 的迭代器.
Iterator简单的来说就是遍历, 遍历什么? 遍历集合元素等.
Iterator接口共有四个方法:
public interface Iterator<E>{ boolean hasNext():如果被迭代的集合还元素没有被遍历,则返回true。 Object next():返回集合里下一个元素。 void remove() :删除集合里上一次next方法返回的元素 void forEachRemaining(Consumer action),这是Java 8为Iterator新增的默认方法,该方法可使用Lambda表达式来遍历集合元素。} }
如果只是普通的迭代输出,那么不会出现什么问题.但是在现实需求中这往往没有什么用,我们还需要做一些额外的操作,比如说
add/remove等。 但是这样做很可能会出现一些很尴尬的事情, 下面我给出一段正确的迭代删除代码:
import java.util.*;public class TestIterator{ public static void main(String[] args) { // 创建集合、添加元素 Collection<String> books = new ArrayList(); books.add("测试1"); books.add("测试2"); books.add("测试3"); Iterator it = books.iterator(); while(it.hasNext()) { // it.next()方法返回的数据类型是Object类型,因此需要强制类型转换 String book = (String)it.next(); System.out.println(book); if (book.equals("测试2")) { // 从集合中删除上一次next方法返回的元素 it.remove(); } } System.out.println(books); }}
上面的代码经过测试是可以正确删除元素的,有疑问的代码估计也就是这一句了
Iterator it = books.iterator();
对list本身进行删除就不行了, 对于这种莫名其妙的问题,我们从源码入手, 首先根据上面的我们先看看ArrayList他是怎么返回Iterator实例的,最终源码如下:
在ArrayList类中有一个私有类Private Itr 我们注意到expectedModCount这个字段,他的初始值是等于modCount的。 那modCount又是干啥的呢 最直接的。 看源码:
我们从源码可以对集合的每一次 add / remove 都会触发一下这个字段,而上面Itr的remove 不管在删除还是添加都会触发一个方法(csdn上截图太麻烦我直接写了 ) checkForComodification();这个方法, 大家可以看看上面的截图而这个 checkForComodification();方法中只有一个功能
if (modCount != expectedModCount) throw new ConcurrentModificationException();
那就是抛出异常~~~~
所以大家应该懂了那段错误的代码为什么会错误了吧。。 因为二个字段不相等啊。 没有同步啊。
如果你问我为什么要这么做,我只能这么跟你说:
Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。
所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性
- Java深入理解 - 迭代器 Iterator 总结
- 深入理解Java的迭代器Iterator
- 深入理解 C++迭代器 iterator
- 深入理解Iterator模式
- java迭代器Iterator的理解
- 深入理解java虚拟机 总结
- 深入理解Java虚拟机总结
- 深入理解Java虚拟机 总结
- Java列表迭代器Iterator的理解
- java迭代器(Iterator)的理解
- 深入理解Java迭代器
- 深入理解Java内存模型 读书总结
- <<深入理解java内存模型>>学习总结
- 《深入理解Java内存模型》读书总结
- 《深入理解Java内存模型》读书总结
- 《深入理解Java虚拟机》读书总结
- Java泛型深入理解小总结
- 《深入理解 Java 内存模型》笔记总结
- Bzoj 2115: [Wc2011] Xor
- 避免重复吐司(Toast)时,显示时间过长
- CentOS下查看apache,php,mysql版本信息
- rensorflow cnn mnist
- Collections工具类/帮助类
- Java深入理解 - 迭代器 Iterator 总结
- Tomcat配置DruidDataSource JNDI数据源例子
- PAT乙级1013
- 连接mysql出现警告:Establishing SSL connection without server's identity verification is not recommended
- java基础知识查漏 二
- 第三章 SQL编程 课上知识点笔记
- GoogleChrome与Firefox的那些事
- GAN︱生成模型学习笔记(运行机制、NLP结合难点、应用案例、相关Paper)
- JAVA WEB从入门到精通day05 javascript学习(3)