范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

List中remove()方法的陷阱,被坑惨了

  来源:blog.csdn.net/pelifymeng2/article/details/78085836
  Java的List在删除元素时,一般会用 list.remove(o) /remove(i) 方法。在使用时,容易触碰陷阱,得到意想不到的结果。总结以往经验,记录下来与大家分享。
  首先初始化List,代码如下:  package com.cicc.am.test;   import java.util.ArrayList; import java.util.List;   public class ListTest {    public static void main(String[] args) {   List list=new ArrayList();   list.add(1);   list.add(2);   list.add(3);   list.add(3);   list.add(4);   System.out.println(list);  } }
  输出结果为[1, 2, 3, 3, 4]
  1、普通for循环遍历List删除指定元素-- 错误 !!! for(int i=0;i=0;i--){  if(list.get(i)==3){   list.remove(i);  } } System.out.println(list);
  输出结果:[1, 2, 4]
  4、foreach遍历List删除元素-- 错误 !!! for(Integer i:list){     if(i==3) list.remove(i); } System.out.println(list);
  抛出异常: java.util.ConcurrentModificationException
  foreach 写法实际上是对的 Iterable、hasNext、next方法的简写。因此从 List.iterator() 源码着手分析,跟踪iterator() 方法,该方法返回了 Itr 迭代器对象。   public Iterator iterator() {         return new Itr();     }
  Itr 类定义如下:  private class Itr implements Iterator {         int cursor;       // index of next element to return         int lastRet = -1; // index of last element returned; -1 if no such         int expectedModCount = modCount;           public boolean hasNext() {             return cursor != size;         }           @SuppressWarnings("unchecked")         public E next() {             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();             }         }           final void checkForComodification() {             if (modCount != expectedModCount)                 throw new ConcurrentModificationException();         }     }
  通过代码我们发现 Itr 是 ArrayList 中定义的一个私有内部类,在 next、remove方法中都会调用checkForComodification 方法,该方法的 作用是判断  modCount != expectedModCount 是否相等,如果不相等则抛出ConcurrentModificationException 异常。
  每次正常执行 remove 方法后,都会对执行 expectedModCount = modCount 赋值,保证两个值相等,那么问题基本上已经清晰了,在 foreach 循环中执行 list.remove(item); ,对 list 对象的 modCount 值进行了修改,而 list 对象的迭代器的 expectedModCount 值未进行修改,因此抛出了ConcurrentModificationException 异常。
  5、迭代删除List元素-- 正确 !
  java中所有的集合对象类型都实现了Iterator接口,遍历时都可以进行迭代:  Iterator it=list.iterator();  while(it.hasNext()){   if(it.next()==3){    it.remove();   }         } System.out.println(list);
  输出结果:[1, 2, 4]
  Iterator.remove()  方法会在删除当前迭代对象的同时,会保留原来元素的索引。所以用迭代删除元素是最保险的方法,建议大家使用List过程
  中需要删除元素时,使用这种方式。学习资料:Java进阶视频资源
  6、迭代遍历,用list.remove(i)方法删除元素-- 错误 !!! Iterator it=list.iterator();  while(it.hasNext()){   Integer value=it.next();    if(value==3){    list.remove(value);   }  } System.out.println(list);
  抛出异常: java.util.ConcurrentModificationException ,原理同上述方法4.
  7、List删除元素时,注意Integer类型和int类型的区别.
  上述Integer的list,直接删除元素2,代码如下:  list.remove(2); System.out.println(list);
  输出结果:[1, 2, 3, 4]
  可以看出,List删除元素时传入数字时,默认按索引删除。如果需要删除Integer对象,调用 remove(object) 方法,需要传入Integer类型,代码如下: list.remove(new Integer(2)); System.out.println(list);
  输出结果:[1, 3, 3, 4]
  总结:
  1、用for循环遍历List删除元素时,需要注意索引会左移的问题。
  2、List删除元素时,为避免陷阱,建议使用迭代器iterator的remove方式。
  3、List删除元素时,默认按索引删除,而不是对象删除。

广东电网发力超充充电5分钟,续航两百公里文羊城晚报全媒体记者马灿实习生赵鑫娆通讯员沈甸近日,广东电网电动汽车服务有限公司(以下简称广东电动)联手广汽埃安新能源汽车有限公司(以下简称广汽埃安),在广州南大干线合作投建的集超证监会鼓励相关机构在不损害投资者利益的前提下开展行业网络安全技术应用昝秀丽中国证券报中证网中证网讯(记者昝秀丽)证监会4月29日消息,证监会起草了证券期货业网络安全管理办法(征求意见稿)(以下简称办法),并向社会公开征求意见。在网络安全促进与发展方证监会鼓励相关机构在不损害投资者利益的前提下开展行业网络安全技术应用证监会鼓励相关机构在不损害投资者利益的前提下开展行业网络安全技术应用财联社4月29日电,证监会就证券期货业网络安全管理办法(征求意见稿)公开征求意见。在网络安全促进与发展方面。一是北京银保监局政策性农业保险充分利用互联网技术不断优化服务流程,实现数据多跑腿农户少跑路北京商报讯(记者陈婷婷胡永新)4月27日,北京商报记者从北京银保监局获悉,2021年北京农业保险综合费用率仅12。7,低于全国平均水平6。4个百分点综合赔付率高于全国平均水平10个手机内存卡被取消,完全是意料之中的事!跟不上时代步伐终被淘汰今天要跟大家聊一聊一个古老的话题。第一部智能手机就是128G起步的朋友,应该没有接触过内存卡这种东西。毕竟手机内存卡是顺应手机储存不足而存在的,当年的功能机和初期智能手机在内存这块互联网时代,家居行业迎来新常态面对行业的激烈竞争,不少传统的家居类企业纷纷转型,希望能为企业赢得新的发展机遇,而大部分的转型由于其盲目性和缺乏对互联网人群的研究而处于疲软状态,并未像最初想象的那么简单。当下,互电力北斗开启新疆电网无人机巡检规模化应用时代远程终端控制系统正常,RTK数据回传正常,北斗无人机各项参数均处于正常范围,请求开展线路巡视作业。5月18日,新疆电力北斗精准服务网首次在750千伏凤乌线路为无人机自主巡检提供高精互联网医疗时代,如何保障网络安全?随着互联网大数据云计算技术的快速发展,我国医疗机构的信息化程度越来越高,逐步向数字化医疗智慧医疗发展。然而,新型技术的使用也带来新的安全风险。近年来,医疗系统遭遇网络攻击的事件时有华为造车上瘾!就差亲自上手了,这次联合长安宁德时代这应该是华为参与程度最深的汽车品牌,被命名为阿维塔,旗下第一款情感智能电动轿跑SUV阿维塔11,新车已于5月20号正式开启预订,同时造型和内饰官图也正式发布。阿维塔科技是由长安汽车张琦老师短短三周抖音爆火,知识付费的时代跨步走来了张琦老师从五月份突然爆火,大多数人随时可以刷到,播放量上亿次,增粉5000万,据说变现500个W往上,是不是很神奇,在短视频时代没有不可能!根据相关统计移动互联网用户12亿,短视频骁龙87012GB256GB1亿像素,跌至1699元,千元机配置天花板国内手机市场销量最好的还是千元机,很多用户虽然能够买得起四五千元高端机,但是智能手机更新换代太快了,很多网友觉得没有必要买太贵的手机,因此千元机是很好的选择,对于大多数用户来说,现
不用散热背夹也能满帧畅玩原神?vivoX80性能深测刚刚发布的vivoX80系列在定位上的调整印象深刻,尤其是这次的X80标准版,除了继承vivoX系列高端水准的优秀做工质感,还搭载了大家期待已久的天玑9000旗舰平台,并配以vivV1天玑9000双芯加持vivoX80杀入安兔兔安卓旗舰性能榜TOP5近日,安兔兔发布了4月安卓旗舰手机性能排行榜,搭载天玑9000的vivoX80凭借近102万平均分成功杀到第四名。根据榜单显示,在性能排名上游戏手机依然遥遥领先,排名前三的都是骁龙广汽集团14月汽车销量同比增7。1新能源汽车销量同比翻番5月6日晚间,广汽集团(601238)发布4月产销快报。广汽集团14月累计生产汽车72。67万辆,同比增长8。1累计销售汽车73。25万辆,同比增长7。1,产销同比均实现正增长。具什么才是品牌影响力?1万元的4G折叠屏手机数秒内被抢购一空文章开始之前我们讨论一下品牌的作用到底是什么?从小编的观点重要的作用就是提高产品溢价,在同等产品的情况下可以卖出更好更高的价格便是品牌带来的影响。而这一点华为做到了,很难想象在20P50E销量遇冷,几乎无人问津,为何大家不再钟爱华为手机?前段时间华为推出的P50E着实让大家看到了不同配色在这款手机上的表现,整体设计设计风格也相对比较凸显。不过,让人意外的是华为P50E正式发售后,市场表现没有了以往火爆抢购的场景,甚荣耀70系列入网天玑9000索尼IMX766,正式回归旗舰阵营?近日,一款型号为FNEAN00的荣耀新机正式入网工信部,根据其配置与内部代号来看,这款手机很可能是即将发布的荣耀70系列中的一款,并且还有不少数码博主爆料,荣耀70系列将会推出中杯苹果再次邀请一批开发者参加WWDC22全球开发者大会IT之家5月24日消息,今日,苹果开始向申请参加WWDC22全球开发者大会的开发者发出额外邀请函,以填补因之前邀请的开发者没有回复或无法参加而形成的空缺。IT之家了解到,4月6日,比亚迪10个工厂即将全部投产,产能总和大于特斯拉对国产车企来说,今年注定是承上启下的一年承上是因为去年中国汽车市场在疫情的影响下,销量也取得了不错的成绩,今年上半年又因为新能源汽车与燃油汽车的交锋,对汽车市场打开了新的道路启下是4万元!云米4K激光影院上市4500ANSI流明150英寸巨幕5月24日,云米宣布旗下K激光投影仪Royal上市,售价40000元。该投影仪隶属于云米的全新高端AI品牌,可调节80150的巨幕画幅,营造IMAX观影氛围,身临其境,在家也能享受海豹发布会不提自动驾驶,激光雷达已申报,比亚迪在憋大招?相信这两天,大家已经被比亚迪海豹的车型的新闻刷屏了,各种对标特斯拉Model3,各种CTB电池技术厉害满天飞,在海豹的发布会上,全程几乎都在讲CTB电池技术,对于海豹的智能化方面,小米发布首款激光打印机一体机小米发布首款激光打印一体机K200,主要是在使用便捷方面了做了大升级,比如通过AirTap碰传功能,直接通过手机NFC连接,碰一碰就可以连接,也可以碰一碰打印。无需安装复杂的驱动就