当前位置: 首页 > news >正文

佛山制作网站企业西宁网站建设高端

佛山制作网站企业,西宁网站建设高端,网站建设打造营销型网站,无锡网建公司一、源码角度分析Java 循环中删除数据为什么会报异常 相信大家在之前或多或少都知道 Java 中在增强 for中删除数据会抛出#xff1a;java.util.ConcurrentModificationException 异常#xff0c;例如#xff1a;如下所示程序#xff1a; public class RmTest {public sta…一、源码角度分析Java 循环中删除数据为什么会报异常 相信大家在之前或多或少都知道 Java 中在增强 for中删除数据会抛出java.util.ConcurrentModificationException 异常例如如下所示程序 public class RmTest {public static void main(String[] args) {ListString list new ArrayList();list.add(001);list.add(002);list.add(003);list.add(004);for (String l : list) {if (Objects.equals(l, 002) || Objects.equals(l,003)) {list.remove(l);}}System.out.println(list);} }运行后会发现抛出了异常 特别是一些新手小伙伴一不注意就陷入其中当然解决方法也特别简单可以转为迭代器然后使用迭代器的 remove 方式删除数据或者使用循环下标的方式通过下标进行删除但需要注意正向循环和反向循环如果是正向循环的话需要注意计算下标位置不过不要担心下面我们都会一一进行介绍。 首先来分析下为什么在增强 for 中会出现java.util.ConcurrentModificationException 异常这里现将java编译成class形式看增强 for最终是以何种形式执行的 javac RmTest.java编译后的内容如下 public class RmTest {public RmTest() {}public static void main(String[] var0) {ArrayList var1 new ArrayList();var1.add(001);var1.add(002);var1.add(003);var1.add(004);Iterator var2 var1.iterator();while(true) {String var3;do {if (!var2.hasNext()) {System.out.println(var1);return;}var3 (String)var2.next();} while(!Objects.equals(var3, 002) !Objects.equals(var3, 003));var1.remove(var3);}} }可以看到增强for最终是编译成迭代器的方式进行遍历数据但需要注意的是删除数据依然使用的 List 中的 remove 方法通过抛出的异常链可以看出问题发生在了 next 方法中的 checkForComodification 方法下 下面看到 ArrayList 下迭代器的 next 方法中在 Itr 类下 在这个方法中首先调用了 checkForComodification 方法正好上面的异常链中也涉及到了 checkForComodification 方法下面进到该方法中 这里是不是看到了熟悉的 ConcurrentModificationException 异常只要 modCount 和 expectedModCount 不相等就会抛出该异常下面看下 expectedModCount 的声明位置 在迭代器内部声明的并且起始值等于 modCount而 modCount 则在定义在 AbstractList 在迭代器的外部这里还记得前面迭代器中使用的是 List 中的 remove 方法删除的数据这里看到该方法中 该方法实际的删除逻辑在 fastRemove 方法中继续看到该方法下 看到这里是不是很直观了modCount 数值发生了变化而迭代器中的expectedModCount 没有随之修改就导致 expectedModCount ! modCount 而抛出异常。 我们都知道使用迭代器中的 remove 方式是不会引发异常的比如 public class RmTest {public static void main(String[] args) {ListString list new ArrayList();list.add(001);list.add(002);list.add(003);list.add(004);IteratorString iterator list.iterator();while (iterator.hasNext()) {String l iterator.next();if (Objects.equals(l, 002) || Objects.equals(l, 003)) {iterator.remove();}}System.out.println(list);}}运行结果 为什么迭代器的 remove 可以呢下面看到该方法中 可以看出迭代器的 remove 同样也是使用了 List 中的 remove 方法但它会在删除后重置 expectedModCount 的值使其保持和 modCount 一致因此就不会触发上面的异常。 看到这里应该明白为什么会抛出异常了但为什么这样设计呢这里可以总结下其中modCount主要表示集合被修改的次数expectedModCount表示迭代器内部维护的集合被修改的次数。当modCount和expectedModCount不相等时则表示肯定有其他某个地方对集合进行了修改此时如果继续使用迭代器遍历集合就可能会出现遍历到非预期的元素或者下个元素不存在了因此只要expectedModCount和modCount保持一致数据就可认为是可信的。 通过这里也能给我们警醒如果需要在并发情况下操作集合一定要选用线程安全的集合。 下面再补充下如果不用增强for使用下标自增的方式删除是否可行吗 public class RmTest {public static void main(String[] args) {ListString list new ArrayList();list.add(001);list.add(002);list.add(003);list.add(004);for (int i 0; i list.size(); i) {String l list.get(i);if (Objects.equals(l, 002) || Objects.equals(l,003)) {list.remove(i);}}System.out.println(list);} }运行后 发现 003 并没有被移除因为当移除了 002 后002 后的数据顺势向前移位原本003的下标为 2 移位后变成了 1 但下标 i 继续增长便会错过后面的数据那怎么解决呢既然后面的数据向前移位对下标i也向前移位就是了 public class RmTest {public static void main(String[] args) {ListString list new ArrayList();list.add(001);list.add(002);list.add(003);list.add(004);for (int i 0; i list.size(); i) {String l list.get(i);if (Objects.equals(l, 002) || Objects.equals(l,003)) {list.remove(i);i i-1;}}System.out.println(list);} }运行后数据正常 既然正向遍历下标需要移位那如果反过来反向循环不就可以不管下标了吗 public class RmTest {public static void main(String[] args) {ListString list new ArrayList();list.add(001);list.add(002);list.add(003);list.add(004);for (int i list.size() - 1; i 0; i--) {String l list.get(i);if (Objects.equals(l, 002) || Objects.equals(l, 003)) {list.remove(i);}}System.out.println(list);} }运行后数据正常
http://www.sadfv.cn/news/95726/

相关文章:

  • 手机网站做桌面快捷方式wordpress邮箱验证注册
  • dw做网站的所有流程版面设计的原则
  • 做电商需要哪些网站购物网站的搜索功能是怎么做的
  • app和微网站的对比分析滨州外贸网站建设
  • 电商网站运维怎么做常熟网站建设哪家好
  • 想建书画网站怎么做的免费网站软件下载大全动漫
  • 网站建设报价清单手机建站程序免费下载
  • flash网站后台网站建设方案概述
  • 自适应企业网站模板域名后有个wordpress
  • 网站建设侵权织梦系统做的商城网站
  • 建立网站的目的晚上睡不着推荐个网站
  • wordpress全站美化wordpress外贸主题免费下载
  • 好的销售网站定制网站建设制作商
  • 网站数据库怎么做同步吗廊坊seo排名霸屏
  • 建设通网站是筑龙网的吗怎么用源码建站
  • 车险网站模版网站建设的五类成员
  • 全屏 单页网站关于加强教体局网站建设
  • 资阳住房和城乡建设厅网站西城区网站建设
  • 月牙河做网站公司企业网站如何做
  • 长沙seo网站优化黄页广告网站
  • 如何利用影视网站做cpawordpress的主机要求
  • 网站开发专家新民正规网站建设价格咨询
  • 建设银行网站开通查询密码扶风做网站
  • 腾云网建站网站多级导航效果
  • 学雷锋做美德少年网站网站详情一般是什么公司做
  • 云天下网站建设线上店免费推广的软件
  • 做响应式网站最大宽度python采集更新wordpress
  • 赤峰建设局网站响应式网站的优缺点
  • 手机门户网站模板网站文件夹权限设置
  • 主流网站关键词排名注册了域名之后怎么做网站