当前位置: 首页 > 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.hkea.cn/news/14323821/

相关文章:

  • 合理规划网站大连企业制作网站
  • 保定市建设施工许可证查询网站如何自学网站后台
  • 人社部能力建设中心网站营销型网站建设沈阳
  • 网站建设 南昌有名的wordpress主题
  • 网站建设模板哪里有湖南网页设计培训网站建设
  • 分销网站制作条件周口市规划建设局网站
  • 网站建设业务员好做吗郑州餐饮网站建设公司排名
  • 书生商友网站建设制作网页费用
  • 咸阳网站建设公司桂林卖手机网站
  • 厦门网站建设公司闽icpwap版网站 加app提示
  • 网站到期续费吗网站建设中模
  • php做的网站怎么加密吉林网站建设司
  • 网站怎么做能让人搜到苏州做网站推广哪家好
  • 团购网站app制作自己制作广告
  • 建设厅网站如何查询企业信息安联建设集团股份公司网站
  • 科技建筑公司网站网站搭建免费官网
  • 双线网站开发公司商铺租金资金回笼慢的原因
  • 经典的jq查询网站网站维护提示怎么做
  • 建站行业解决方案足球比赛直播 视频直播
  • 网站备案号官网uc投放广告网站要自己做吗
  • 北京做网站哪个好做公众号首图的设计网站
  • 网站开发和软件开发哪个好开广告店需要什么技术
  • 专业网站建设服务公司哪家好域名防红跳转网址生成
  • html 单页网站以前可以做视频的网站
  • 杭州餐饮 网站建设网站域名怎么申请
  • 网站建设工作流程图桂电做网站的毕设容易过嘛
  • 深圳做网站的公司的区域关于做电商网站导流项目
  • 网站开发怎么确定价格手机网站焦点图代码
  • 个人网站样式wordpress怎么建商场
  • 网站营销做的好的律师什么网站做淘宝素材比较好