进阶JAVA篇- Collcetions 工具类与集合的并发修改异常问题
目录
1.0 集合的并发修改问题
1.1 如何解决集合的并发修改问题
2.0 Collcetions 工具类的说明
1.0 集合的并发修改问题
我们可以简单的认为,就是使用迭代器遍历集合时,又同时在删除集合中的数据,程序就会出现并发修改异常的错误。
代码如下:
import java.util.ArrayList; import java.util.Iterator; import java.util.List;public class Abnormal {public static void main(String[] args) {//创建对象,再添加数据List<String> list = new ArrayList<>();list.add("张三");list.add("陈七");list.add("李麻子");list.add("李四");list.add("王五");//利用迭代器进行遍历,先创建迭代器Iterator<String> iterator = list.iterator();while (iterator.hasNext()){String a = iterator.next();if (a.contains("李")){list.remove(a);}}System.out.println(list);} }运行结果如下:
像以上情况,一边遍历的时候去删除数据,直接会报错,原因是因为集合是一个可变的容器,每删一个数据,容器的大小都会改变,那么数据存放的位置也会相应的改变。迭代器遍历可能不好理解,我们就换成普通的 for 循环,但是两者的出现的 Bug 是一样的。
代码如下:
import java.util.ArrayList; import java.util.List;public class Text_For {public static void main(String[] args) {//创建对象,再添加数据List<String> list = new ArrayList<>();list.add("张三");list.add("陈七");list.add("李麻子");list.add("李四");list.add("王五");for (int i = 0; i < list.size(); i++) {String a = list.get(i);if (a.contains("李")){list.remove(a);}}System.out.println(list);} }运行结果如下:
发现用 for 循环竟然不报错,原因可能是没有用迭代器遍历严谨吧,以上的两种代码的效果都是一样的,会出现 Bug ,就是本来要删除带 ”李“ 的名字,但是发现名字还有一个”李四“,没有被删除,那是什么原因呢?
直接会把 ”李四“ 忽略掉,这就是这出现 Bug 的地方。
1.1 如何解决集合的并发修改问题
对于用普通的 for 循环来遍历的代码来说可以有两种方法;第一个方法就是每一次删除数据的时候,都要进行 i--; 第二方法就是从尾开始遍历。
代码如下:
第一种方法
import java.util.ArrayList; import java.util.List;public class Text_For {public static void main(String[] args) {//创建对象,再添加数据List<String> list = new ArrayList<>();list.add("张三");list.add("陈七");list.add("李麻子");list.add("李四");list.add("王五");for (int i = 0; i < list.size(); i++) {String a = list.get(i);if (a.contains("李")){list.remove(a);i--;}}System.out.println(list);} }运行结果如下:
成功把”李四“也删除掉了。
第二种方法
import java.util.ArrayList; import java.util.List;public class Text_For {public static void main(String[] args) {//创建对象,再添加数据List<String> list = new ArrayList<>();list.add("张三");list.add("陈七");list.add("李麻子");list.add("李四");list.add("王五");for (int i = list.size() - 1; i >= 0; i--) {String a = list.get(i);if (a.contains("李")){list.remove(a);}}System.out.println(list);} }运行结果如下:
一样也可以把”李四“删除掉。
对于用迭代器来遍历的代码来说,只能把集合对象.remove(String str) 换成迭代器对象.remove() 。
代码如下:
import java.util.ArrayList; import java.util.Iterator; import java.util.List;public class Abnormal {public static void main(String[] args) {//创建对象,再添加数据List<String> list = new ArrayList<>();list.add("张三");list.add("陈七");list.add("李麻子");list.add("李四");list.add("王五");//利用迭代器进行遍历,先创建迭代器Iterator<String> iterator = list.iterator();while (iterator.hasNext()){String a = iterator.next();if (a.contains("李")){iterator.remove();}}System.out.println(list);} }运行结果如下:
也是可以的。
对于增强 for 循环还有利用 Lambda 表达式的循环都不可以用来一边遍历集合,一边删除数据,无法解决集合的并发修改异常。
2.0 Collcetions 工具类的说明
是一个用来操作集合的工具类。
以代码为例来介绍具体的静态方法:
import java.util.ArrayList; import java.util.Collections; import java.util.List;public class Text_Collections {public static void main(String[] args) {String s1 = "李四";String s2 = "张三";String s3 = "王五";String s4 = "张麻子";List<String> list = new ArrayList<>();//1. addAll() 为集合批量添加数据Collections.addAll(list,s1,s2,s3,s4);System.out.println(list);//输出结果为:[李四, 张三, 王五, 张麻子]//2. shuffle() 打乱list集合中的元素顺序Collections.shuffle(list);System.out.println(list);//输出结果为:[王五, 张麻子, 李四, 张三]//3. sort() 对list集合的元素进行升序排序Collections.sort(list);System.out.println(list);//输出结果为:[张三, 张麻子, 李四, 王五]} }运行结果如下:
补充第三种方法,如果对自定的对象进行排序的话,默认的 sort 是会报错的,所以得自定义比较,创建一个比较器。
代码如下:
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List;public class Text_Collections {public static void main(String[] args) {Student s1 = new Student("张三",19);Student s2 = new Student("李四",33);Student s3 = new Student("王五",21);List<Student> list = new ArrayList<>();Collections.addAll(list,s1,s2,s3);//自定义,根据年龄进行排序Collections.sort(list, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return o1.getAge()- o2.getAge();}});System.out.println(list);} }运行结果如下:
相关文章:
进阶JAVA篇- Collcetions 工具类与集合的并发修改异常问题
目录 1.0 集合的并发修改问题 1.1 如何解决集合的并发修改问题 2.0 Collcetions 工具类的说明 1.0 集合的并发修改问题 我们可以简单的认为,就是使用迭代器遍历集合时,又同时在删除集合中的数据,程序就会出现并发修改异常的错误。 代码如下&…...
npm WARN npm npm does not support Node.js v12.18.3
npm 不支持 Node.js v12.18.3 , npm和node的版本不匹配。 npm WARN npm npm does not support Node.js v12.18.3 npm WARN npm You should probably upgrade to a newer version of node as we npm WARN npm cant make any promises that npm will work with this v…...
转行做程序员,多晚都不晚
大家好啊,我是董董灿。 最近有不少小伙伴加我微信咨询一些问题,有同学想了解AI行业的现状,想着转行的,也有在校生想了解毕业后工作方向的,当然也有想学习编程知识的。 诚惶诚恐,没想到之前写的文章&#…...
自动化运维ansible
一、Ansible概述: 是一个配置管理系统(configuration management system),当下最流行的批量自动化运维工具之一。 Ansible是一个开源的自动化工具,用于配置管理、应用程序部署和编排等 IT 任务的执行。它专注于简单性和可扩展性,并…...
记录:Unity脚本的编写4.0
目录 前言导入音乐编写脚本 前言 之前使用脚本对uniry中的模型进行了控制,诸如使用键盘控制对象模型的移动或者使用鼠标对对象模型进行角度的切换(或者是类似的东西),而我们在游戏的过程中,总是伴随着一些好听的bgm&a…...
vue中引入jquery解决跨域问题
1、vue 工程文件 package.json 中 引入 “dependencies”: { “jquery”:“^2.2.4” }, 2、控制台执行命令,当前工程文件夹下 cnpm install 3、修改的vue文件中 加入 import $ from ‘jquery’ 4、调用 ajax请求 $.ajax({url:http://192.168.0.10:9099/strutsJspA…...
车规MCU开发工具之Vector DaVinci Configurator执行arxml合并操作
环境 Step1 导入要合并的arxml 、 Step 2 比较、合并过程 <完>...
数字滚动动效(纯HTML5版和Vue版本)
数字从0到指定数字的滚动动效,直接上代码; H5 <!DOCTYPE html> <html> <head><style>/* 设置数字显示的样式 */.counter {font-weight:700;font-size: 36px;color: #333;}</style> </head> <body><div cl…...
Leetcode—2530.执行K次操作后的最大分数【中等】(C语言向上取整数学公式)
2023每日刷题(五) Leetcode—2530.执行K次操作后的最大分数 向上取整思想 参考了这篇文章 有人肯定会问,这个向上取整为什么是这样来的。接下来我简单讲解一下。 数学式: x y 数学式:\frac{x}{y} 数学式:…...
CMakeList 编写示例
cmake_minimum_required(VERSION 3.8) #指定cmake的最小版本 set(PROJECT_NAME Untitled_1) #初始化变量 project(${PROJECT_NAME} VERSION 1.0) #创建一个project set(CMAKE_AUTOMOC ON) #初始化内置变量, 该变量为Qt工程专属变量 set(CMAKE_AUTORCC ON) set(CMAKE_A…...
OSI笔记
由7层组成,由下自上分别为: 物理层(硬件方面,例如物理网络设备、布线电缆、光纤等), 传输数据主要是比特流0 1 、电信号数据链路层(确定了0 1 的分组方式,通过广播的方式࿰…...
C++之前置声明
在C中,前置声明是一种声明类或函数的方式,但并不定义它们。 前置声明的主要目的是为了解决编译时的依赖性问题,提高编译效率,并允许更灵活的代码组织。 原理 C前置声明可以减少头文件依赖的原理在于,通过前置声明&am…...
用3D扫描生成合成数据
合成数据集(Synthetic Datasets)正在成为计算机视觉模型训练的标准部分。 虽然新工具使合成数据集变得更容易访问,但除了标准机器学习过程之外,许多工具还需要对 3D 建模有基本的了解。 最简单的捷径是从现实世界中获取现有对象并…...
pip安装依赖报错
执行命令时 pip install --upgrade pip 报错: pip : 无法将“pip”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。pip install --upgrade pip~~~ Category…...
规范的项目流程图怎么写
编写规范的项目流程图可以遵循以下步骤: 1.明确项目目标:首先,明确项目的目标以及需要实现的结果。这有助于确定项目的范围和要求。 2.识别项目任务:识别和列出所有的任务,这可以包括获得资源、实施动作、收集信息等…...
模型部署笔记--Pytorch-FX量化
目录 1--Pytorch-FX量化 2--校准模型 3--代码实例 3-1--主函数 3-2--prepare_dataloader函数 3-3--训练和测试函数 1--Pytorch-FX量化 Pytorch在torch.quantization.quantize_fx中提供了两个API,即prepare_fx和convert_fx。 prepare_fx的作用是准备量化&#…...
解决XXLJOB重复执行问题--Redis加锁+注解+AOP
基于Redis加锁注解AOP解决JOB重复执行问题 现象解决方案自定义注解定义AOP策略redis 加锁实践 现象 线上xxljob有时候会遇到同一个任务在调度的时候重复执行,如下图: 线上JOB服务运行了2个实例,有时候会重复调度到同一个实例,有…...
云安全(1)--初识容器逃逸之特权容器逃逸
文章目录 前言privileged,特权容器逃逸环境配置实际利用实际环境利用计划任务/var/spool/cron/crontabs/ 适用于ubuntu debain/var/spool/cron 适用于centos ld.so.preloadssh 前言 在10.15号的上海中华武数杯的渗透赛里做到了一个k8s的题目,这应该是我第一次在比赛…...
二阶系统时域响应
二阶系统微分方程 二阶系统传递函数 二阶系统单位阶跃响应 过阻尼系统 临界阻尼系统 欠阻尼系统 无阻尼系统 二阶系统阶跃响应仿真 在Matlab中进行仿真,设置不同阻尼比2、1、0.5和0,可以得到结论: 阻尼比越小,系统响应速度越快&…...
mstsc改端口为33389
windows 远程默认端口3389不太安全,改成33389防下小人 把下面的2个文本存在后缀.reg的文件,双击导入注册表,"PortNumber"dword:0000826d 这个就是33389对应的端口号的16进制值,要想自己改成其它的换下值即可 Windows …...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...







