java迭代器不能修改集合值_关于使用迭代器对集合进行遍历时,不能对集合进行修改的论证...
关于使用迭代器对集合进行遍历时,不能对集合进行修改的论证## 标题 ##
摘要:迭代器再帮助我们进行对集合的元素进行遍历提供了有效的方法,java采用迭代器模式能在不暴露集合对象内部元素的情况下,对元素进行访问。
1.使用迭代器的优点
Collection中的remove()方法需要先查找到需要删除元素的位置,这本身就需要一定的开销
如果在使用迭代器进行对集合的遍历时,对集合自身产生结构上的变化的时候(add.remove,clear等),例如:遍历时对集合当前向的下一项做了删除的操作,当再一次调用next(),就会出现混乱,下文会从源码的角度对其进行分析。
2.接口Iterator源码
public interface Iterator{
//获取下一个元素,第一次调用给出第一项,第二次给出第二项,。。。
E next();
//是否存在下一个,存在true,不存在false
boolean hasNext();
//从底层集合中删除迭代器返回的最后一个元素,就是next()返回的集合中的元素
default void remove() {
throw new UnsupportedOperationException("remove");
}
//对每个剩余的元素进行一定的操作
default void forEachRemaining(Consumer super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
3.测试实例
@Test
public void test_Iterator() {
List list = new ArrayList<>();
list.add("唐三藏");
list.add("孙悟空");
list.add("猪八戒");
list.add("沙和尚");
list.add("白龙马");
for(Iterator iter = list.iterator();iter.hasNext();{
if("猪八戒".equals(iter.next())) {
list.add("高小姐");
}
}
}
测试结果:java.util.ConcurrentModificationException
4.源码解读
private class Itr implements Iterator{//Itr类作为ArrayList的内部类
int cursor; // 下一个元素的索引
int lastRet = -1; // 最后一个元素索引
int expectedModCount = modCount;//预期集合元素数量
public boolean hasNext() {
//size外部类集合的大小
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
//关键一步,调用checkForComodification()会去校验expectedModCount 和modCount是否相等,不等抛异常
//modCount 字段作为外部类结构修改次数的记录,为子类提供快速迭代,上文实例抛错就是出自此处
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
源码解读:对集合进行迭代器遍历的时候,调用hashNext(),查看下一个元素的索引是否和集合的大小相等,相等表示已经到了集合的末尾,不存在下一个元素返回false;调用next()方法会先调用checkForComodification()方法来确保对集合修改次数一致,不一致抛异常,如果此时我们调用集合的remove(int index),就会去修改modCount 字段的次数,等下次再调用迭代器的next()方法的时候,值就会不一致 ,出现异常。同时,从逻辑的角度上来说,当我们对集合进行迭代的时候,如果对集合进行结构上的修改,直接会影响迭代器的遍历,产生不可预知的结果,所以在迭代器进行遍历的时候集合是不能对集合自身进行修改的。
java迭代器不能修改集合值_关于使用迭代器对集合进行遍历时,不能对集合进行修改的论证...相关推荐
- java函数返回多个值_深入理解被调函数与主调函数之间的传值、传址、值返回、址返回...
函数的英文是function,有功能的意思,函数的作用在于合理分配功能,增强程序的可读性.合理分解功能,降低程序的复杂性.隐藏函数内部的数据和实现,尽可能将问题局限于函数本身. 函数可以理解为一种功能 ...
- python集合运算_从零开始学Python - 第014课:常用数据结构之集合
在学习了列表和元组之后,我们再来学习一种容器型的数据类型,它的名字叫集合(set).说到集合这个词大家一定不会陌生,在数学课本上就有这个概念.通常我们对集合的定义是"把一定范围的.确定的.可 ...
- r语言集合补集_【高中数学必修1研读】之一“第一章 集合与函数概念”
第一章:集合与函数概念 [导入例子] "神舟"五号载人航天飞船离地面的距离随时间的变化而变化:上网费用随着上网时间的变化而变化:出国旅游人数日益增多:城市绿化面积不断扩大..... ...
- struts 修改拦截器修改返回值_关于struts2简单的介绍与示例
Apache Struts 2是一个用于开发Java EE网络应用程序的开放源代码网页应用程序架构.它利用并延伸了Java Servlet API,鼓励开发者采用MVC架构. 缘起于Apache St ...
- java获取注解的属性值_反射+自定义注解,实现获取注解标记的属性
目标:通过自定义注解 @Ignore 注解,觉得是否读取指定类的属性. 运行结果: [main] INFO util.FruitInfoUtil -水果的名字为:entity.Apple [main] ...
- java冒泡排序找最大的值_(13)數組操作:遍歷、輸出最大值、冒泡排序、選擇排序,java已有的排序方法、折半查找...
1.數組遍歷 /* * 獲取數組中元素,遍歷 */ int []y=new y[3]; for(int i=0;i { System.out.println("y["+i+&quo ...
- std::list 修改某个值_在WordPress首页不显示某个分类文章的做法
WordPress作为博客站点很好用,但可惜的是没有微博/twitter之类快速短文的功能,如果设置一个分类来放置这类短文,首页又会显得杂乱而没有章法,按照网络上的教程,这个问题有几种解决办法,自己采 ...
- java 怎么获取键的值_在 Java 中如何获取 Map 的所有键和值
在 Java 中可以通过 map.entrySet() 方法获取 Map 的所有键和值. Map map = new HashMap<>(); // Get keys and values ...
- java逆波兰式求值_波兰式、逆波兰式与表达式求值
波兰式.逆波兰式是<数据结构>课程中讲解关于栈的时候提到的,栈是很简单的一种数据结构.但是这些理论的提出却是计算机早期发展领域的重大突破,值得仔细回味. 1. 中缀表达式 我们在数学中学到 ...
最新文章
- android 九宫格绘制,Android draw9patch.bat 九宫格绘制工具使用
- 携手百度 英特尔三大领域布局人工智能市场
- view函数_数据科学系列:数据处理(6)字符串函数基于R(二)
- Oracle查询优化-01单表查询
- MongoDB练习题
- TSC条码打印机亮红灯解决办法!
- python 矩阵元素平方_NumPy之计算两个矩阵的成对平方欧氏距离
- Java全栈开发---Java ERP系统开发:商业ERP(十二)数据的导入导出(Excel)
- xshell linux 打开多个窗口快捷键,linux,xshell,快捷键
- java实现图片上传后裁剪,把白色背景变成透明图(电子印章)
- Python 创建子线程
- r语言使用linux命令,技术|如何在 Ubuntu 上安装和使用 R 语言
- Fortran语法汇总(上)
- revit二次开发 材质相关
- Microbit蓝芽配对
- 【CMU15-445数据库】bustub Project #0:Trie 树实现(C++ Primer)
- 如何让点聚WebOffice在线编辑ActiveX插件兼容火狐、谷歌、IE各式浏览器
- [质数筛] 质数筛算法详解
- linux 调整屏幕亮度、待机、休眠命令
- docker runc 版本升级
热门文章
- 数据结构(C++)—— 向量(Vector)
- C++ 类中特殊成员变量(常量、静态、引用)的初始化方法
- csrf token invalid什么意思_Spring Cloud Gateway 实现Token校验
- 没有计算机基础可以学python-零基础,没有编程和计算机基础,究竟该怎么自学python?...
- python学习网站-关于python学习,最系统的学习网站看这里
- python代码实例-python程序实例
- python和c语言的区别-c语言和python的区别是什么
- 如何系统的自学python-如何系统地自学Python
- python怎么读写文件-python3 excle(python怎么读写excel文件)
- python自动化办公真的好用吗-python如何实现自动化办公?