Java基础-----集合类(四)

请添加图片描述

文章目录

  • 1. Iterator和ListIterator
    • 1.1 简介
    • 1.2 常用方法
  • 2. remove方法
    • 2.1 比较foreach方式和迭代器方式删除元素
    • 2.2 找原因 -- 迭代器删除操作源码

1. Iterator和ListIterator

1.1 简介

1.Iterator 可以遍历List集合,也可以遍历Set集合; ListIterator只能遍历List集合

2.Iterator 只能单向遍历(向后遍历),ListIterator双向遍历(向前/向后遍历)

3.ListIterator继承Iterator接口,添加新的方法

1.2 常用方法

  • add(E e):将指定的元素插入到集合中,插入位置为迭代器当前位置之前

  • hasNext():正向遍历集合,判断后面是否还有元素,返回boolean类型值

  • next():返回集合中迭代器指向后面位置的元素

  • nextIndex():返回集合中迭代器后面位置元素的索引

  • hasPrevious():反向遍历集合,判断前面是否还有元素,返回boolean类型值

  • previous():返回集合中迭代器指向前面位置的元素

  • previousIndex():返回集合中迭代器前面位置元素的索引

  • set(E e):替换迭代器当前位置的元素

		List<String> list=new ArrayList<>();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        list.add("dd");
        for (Iterator<String> iterator= list.iterator();iterator.hasNext();){
            System.out.println(iterator.next());
        }
		List<String> list=new ArrayList<>();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        list.add("dd");
		//正向遍历
        ListIterator<String > iterator=list.listIterator();
        iterator.add("EEE");
        for (String s : list) {
            System.out.println(s);//EEE aa bb cc dd
        }
		List<String> list=new ArrayList<>();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        list.add("dd");

		ListIterator<String > iterator=list.listIterator();
        iterator.next();
        iterator.add("EEE");
        for (String s : list) {
            System.out.println(s);//aa EEE bb cc dd
        }
        System.out.println("-------------------");
        iterator=list.listIterator();
        for (;iterator.hasNext();){
            System.out.println(iterator.next());
        }
        System.out.println("-------------------");
        iterator=list.listIterator();
        for (;iterator.hasNext();){
            System.out.println(iterator.nextIndex()+"\t"+iterator.next());
        }

运行结果:
在这里插入图片描述

//反向遍历
        ListIterator<String> iterator=list.listIterator(list.size());
        while (iterator.hasPrevious()) {
            System.out.println(iterator.previousIndex()+"\t"+iterator.previous());
        }

运行结果:
在这里插入图片描述

		ListIterator<String> iterator=list.listIterator(list.size());
        while (iterator.hasPrevious()) {
            System.out.println(iterator.previousIndex()+"\t"+iterator.previous());
        }
        iterator.set("GGG");
        System.out.println(list);//[GGG, bb, cc, dd]
----------------------------------------------------------------------------
        ListIterator<String> iterator=list.listIterator(list.size());
        iterator.previous();
        iterator.set("GGG");
        while (iterator.hasPrevious()) {
            System.out.println(iterator.previousIndex()+"\t"+iterator.previous());
        }

        System.out.println(list);//[aa, bb, cc, GGG]

2. remove方法

2.1 比较foreach方式和迭代器方式删除元素

对集合元素进行循环处理增加或删除时,不能使用foreach处理方式,要使用迭代器方式。

  • 使用foreach方法进行删除,报错:java.util.ConcurrentModificationException
		ArrayList<String> list=new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");

        for (String s : list) {
            if ("aaa".equals(s)){
                list.remove(s);
            }
        }
        System.out.println(list);
  • 使用迭代器方式删除元素:
		Iterator<String> iterator=list.iterator();
        while (iterator.hasNext()){
            String x=iterator.next();
            if (x.equals("aaa")){
                iterator.remove();
            }
        }
        System.out.println(list);//[bbb,ccc,ddd]
  • 但是,在foreach对集合中倒数第二个元素进行删除时,不会报错,其他位置的元素都会报错。
		for (String s : list) {
            if ("ccc".equals(s)){
                list.remove(s);
            }
        }
        System.out.println(list);//[aaa,bbb,ddd]

其中,foreach底层也是通过迭代器实现的。

其实,我们在使用迭代器操作时,有两个步骤:

iterator.hasNext();//判断是否有下一个元素

item=iterator.next();//有下一个元素的话,取出

2.2 找原因 – 迭代器删除操作源码

首先,我们进入到Iterator的remove()方法中,找到Itr类,在这个类中我们会看到ArrayList的remove()方法

在这里插入图片描述
在这里插入图片描述

在remove()方法中,看到里面有个checkForComodification()方法

在这里插入图片描述

		final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }

在checkForComodification()方法中,有两个变量:modCount变量和expectedModCount变量,当这两个变量不相同时,就会抛出异常处理(也就是我们在前面遇到的那个异常)

modCount变量:记录集合对象从new出来到现在被修改的次数

expectedModCount变量:迭代器现在期望这个集合被修改的次数

在上面源码中看到:expectedModCount = modCount;只要保持这两个变量相等,删除操作就没有问题。

所以,迭代器不会报错,使用foreach会报错,原因是:

在迭代器中,对这两个变量进行了同步处理,而foreach没有进行同步处理,导致会出现checkForComodification异常出现。


通过查看源码,有一个hasNext()方法,方法中要比较cursor和size

		public boolean hasNext() {
            return cursor != size;
        }

cursor是下一个元素的索引值;size是整个集合元素个数

如果两个元素不相等,即有下一个元素,就返回true。

当删除倒数第二个元素时,cursor通过计算之后,得到cursor=size,导致迭代器认为不存在下一个元素,迭代结束。

整体架构如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/289562.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux学习(9)——RAID与服务器的常见故障

目录 一、服务器常见故障 1、系统不停重启进入不了系统 2、卡在开机界面右下角有fA B2 H8 3、系统安装不上 4、如何进入服务器的bios 5、一般进入阵列卡的快捷键 6.网络不通 7.硬盘不识别 二、RAID相关知识 1、RAID的概念 2、RAID功能实现 3、RAID实现的方式 三、…

2024年01月数据库流行度最新排名

点击查看最新数据库流行度最新排名&#xff08;每月更新&#xff09; 2024年01月数据库流行度最新排名 TOP DB顶级数据库索引是通过分析在谷歌上搜索数据库名称的频率来创建的 一个数据库被搜索的次数越多&#xff0c;这个数据库就被认为越受欢迎。这是一个领先指标。原始数…

2020年认证杯SPSSPRO杯数学建模C题(第一阶段)抗击疫情,我们能做什么全过程文档及程序

2020年认证杯SPSSPRO杯数学建模 C题 抗击疫情&#xff0c;我们能做什么 原题再现&#xff1a; 2020 年 3 月 12 日&#xff0c;世界卫生组织&#xff08;WHO&#xff09;宣布&#xff0c;席卷全球的冠状病毒引发的病毒性肺炎&#xff08;COVID-19&#xff09;是一种大流行病。…

js中函数动态调用

文章目录 一、场景二、方法2.1、动态函数2.2、eval()函数 三、最后 一、场景 在JS开发中&#xff0c;例如有些场景下&#xff0c;后端要求一个功能要请求不同的接口&#xff0c;但是传参及后续逻辑其实都是一样的&#xff0c;有些同学可能会想到在接口url处统一处理就好&#…

51单片机项目(27)——基于51单片机的智能门窗设计

1.功能设计 使用普中51单片机&#xff0c;门窗有自动模式和手动模式。 手动模式下&#xff0c;LCD1602显示屏上显示“manu mode”&#xff0c;通过红外遥控器&#xff0c;控制门窗的开关。其中&#xff0c;按键0代表开窗&#xff0c;按键1代表关窗。&#xff08;使用风扇模拟门…

【Vue2+3入门到实战】(17)VUE之VueCli脚手架自定认创建项目、ESlint代码规范与修复、 ESlint自动修正插件的使用 详细示例

目录 一、本节内容二、VueCli 自定义创建项目三、ESlint代码规范及手动修复1.JavaScript Standard Style 规范说明2.代码规范错误3.手动修正 四、通过eslint插件来实现自动修正 一、本节内容 VueCli脚手架自定认创建项目ESlint代码规范与修复ESlint自动修正插件 二、VueCli 自…

qt 异常汇总

1. C2338 No Q_OBJECT in the class with the signal (编译源文件 ..\..\qt\labelme-master\src\mainwindow.cpp mainwindow头文件中的类没有Q_OBJECT宏定义&#xff0c;或者其子类或者其他依赖没有Q_OBJECT宏定义。 全部qt类都要写上Q_OBJECT. 2. C2385 对connect的访…

uniapp中组件库的Checkbox 复选框 的丰富使用方法

目录 #平台差异说明 #基本使用 #自定义形状 #禁用checkbox #自定义形状 #自定义颜色 #横向排列形式 #横向两端排列形式 API #Checkbox Props #CheckboxGroup Props #CheckboxGroup Event 复选框组件一般用于需要多个选择的场景&#xff0c;该组件功能完整&#xff…

【Github】如何创建一个自己的仓库

一、创建Github账户 不多赘述&#xff0c;进入官网创建账户即可 二、进入个人主页&#xff0c;点击新建仓库 三、按照需求配置仓库信息&#xff0c;点击创建 四、通过git导入代码到仓库 流程大致如下&#xff1a; 1.进入要上传代码的地方&#xff0c;选择打开git命令行界面 2…

DNS主从服务器、转发(缓存)服务器

一、主从服务器 1、基本含义 DNS辅助服务器是一种容错设计&#xff0c;考虑的是一旦DNS主服务器出现故障或因负载太重无法及时响应客户机请求&#xff0c;辅助服务器将挺身而出为主服务器排忧解难。辅助服务器的区域数据都是从主服务器复制而来&#xff0c;因此辅助服务器的数…

Ubuntu软件和vmware下载

https://cn.ubuntu.com/download/desktop VMware 中国 - 交付面向企业的数字化基础 | CN

漏洞复现-天融信TOPSEC static_convert 远程命令执行漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

【Week-P4】CNN猴痘病识别

文章目录 一、环境配置二、准备数据三、搭建网络结构四、开始训练五、查看训练结果六、总结2.3 ⭐torch.utils.data.DataLoader()参数详解6.1 print()常用的三种输出格式6.2 修改网络结构6.2.1 增加池化、卷积和bn层6.2.2 增加卷积、bn、卷积、bn &#x1f368; 本文为&#x1…

界面控件DevExpress Blazor Grid v23.2 - 支持全新的单元格编辑模式

DevExpress Blazor UI组件使用了C#为Blazor Server和Blazor WebAssembly创建高影响力的用户体验&#xff0c;这个UI自建库提供了一套全面的原生Blazor UI组件&#xff08;包括Pivot Grid、调度程序、图表、数据编辑器和报表等&#xff09;。 在这篇文章中&#xff0c;我们将介…

Navicat 技术干货 | 如何查看关系型数据库(MySQL、PostgreSQL、SQL Server、 Oracle)查询的运行时间

在数据库优化中&#xff0c;理解和监控查询运行时间是至关重要的。无论你是数据库管理员、开发人员或是参与性能调优的人员&#xff0c;知道如何查看查询运行时间能为你的数据库操作提供有价值的参考。本文中&#xff0c;我们将探索几款热门的关系数据库&#xff08;如 MySQL、…

❀记忆冒泡、选择和插入排序算法思想在bash里运用❀

目录 冒泡排序算法:) 选择排序算法:) 插入排序算法:) 冒泡排序算法:) 思想&#xff1a;依次比较相邻两个元素&#xff0c;重复的进行直到没有相邻元素需要交换&#xff0c;排序完成。 #!/bin/bash arr(12 324 543 213 65 64 1 3 45) #定义一个数组 n${#arr[*]} #获取数组…

DHTMLX Spreadsheet v5.1.1 Crack

DHTMLX Spreadsheet 5.1 具有新主题、简化的数字格式本地化、与框架的实时集成演示等 推出 DHTMLX Spreadsheet v5.1。新版本提供了一组有用的功能&#xff0c;这对开发人员和最终用户都有吸引力。 首先&#xff0c;新的电子表格版本提供了 4 个内置主题&#xff0c;可以根据您…

【完整代码】网上书店信息管理系统--基于Mysql数据库与java

网上书店信息管理系统 一、需求分析&#xff08;一&#xff09;设计系统的意义以及用途&#xff08;二&#xff09;实现的功能1.用户模块&#xff1a;1、全部图书浏览2、图书搜索3、购物车管理和订单查看4、修改密码 2.书店管理员模块1、图书类别管理2、图书管理3、全部订单查看…

【React】01-React 入门到放弃系列

01-React 入门 背景入门学生成绩录入的表单 小结 背景 由于捣鼓一些项目需要用到React&#xff0c;找了一些文档入门实践了一番。本篇文章以一个学生成绩录入的表单为例子&#xff0c;记录React 入门的一些基础操作。 入门 该操作的前提是本地安装了NodeJS环境。根据官网给的…

Docker入门教程(详解)

Docker容器化 一 入门 1. 引言 &#xff08;1&#xff09;单机部署 场景&#xff1a; 将多个应用部署一台服务器上。 问题 每个应用软件&#xff0c;都会消耗物理资源&#xff0c;共用计算机资源&#xff0c;彼此之间会形成竞争关系。 &#xff08;2&#xff09;多机部署 …