【转载】ArrayList 中数据删除 & fail fast

在循环arrayLlist时,经常会遇到remove操作,那么arrayList的remove的底层是怎么做的?
AbstractList中,有一个属性modCount,这个属性是跟踪list中数据被修改的次数,任何对list的add/remove操作,都将导致modCount++.
在AbstractList中还有一个内部类Itr implements Iterator,Itr是一个list遍历的工具类,当然list.iterator()方法也是返回Itr对象,在Itr中有一个校验位属性expectedModCount;对于一个itr对象,其初始时expectedModCount=modCount.
Iterator是list一个视图,其最终还是操作list的存储结构.在使用iterator遍历时,remove()操作,会导致modCount++(AbstractList.remove()),但是还有expectedModCount=modCount,即在iterator中remove数据,会带来expectedModCount与modCount值的同步.
在Iterator遍历时,next(),remove()方法会校验expectedModCount与modCount值是否一致,如果不一致,就意味着这list数据在iterator外部被修改,此时iterator遍历将会造成ConcurrentModificationException.

AbstractLlist不仅支持普通的iterator,还支持ListIterator(ArrayList,LinkedList均支持),ListIterator增加了遍历时双向游标能力(previous,next),增加了add方法.add方法和remove方法一样也做了expectedModCount和modCount一致性校验.
引申一下,如下四个对list数据删除的代码,有区别吗??
如下是4中循环方式:

1) for(int i=0;i<list.size();i++){
list.remove(i);
}
2) for(int i=list.size()-1;i>=0;i--){
list.remove(i);
}
3)
int size = list.size();
for(int i=size-1;i>-1;i--){
list.remove(i);
}

4) for(Object i : list){
list.remove(i);//如果list中存在多个Object互相equals时,此方法仍然有效.注意list.remove(Object)内部使用了遍历操作,并使用equals来比较对象并删除.
}
5) Iterator it = list.iterator()
while(it.hasNext()){
it.next();
it.remove();
}

1),2),3)是最普通的遍历方式,但是在遍历并有删除操作时,似乎它们执行的结果还有些差距,根据坐标删除,那么1)实事上只会有一半被删掉,1)中每删除一次,计算一次list.size(),但是当前i++,且前端删除会造成数组结构copy.
2)后端删除,不会造成copy,每次都是删除最后一个位置,直至结束
3)因为size没有重新计算,在删除一半数据后,抛出IndexOutOfBoundsException
4)/5)正常

提示:foreach方式最终是转换成了iterator的方式进行.(产生于编译过程中).
原文链接:[http://wely.iteye.com/blog/2228829]

时间: 2024-09-16 09:27:06

【转载】ArrayList 中数据删除 & fail fast的相关文章

【转载】ArrayList 中数据删除

本文转载自http://shift-alt-ctrl.iteye.com/blog/1839147   在循环arrayLlist时,经常会遇到remove操作,那么arrayList的remove的底层是怎么做的? AbstractList中,有一个属性modCount,这个属性是跟踪list中数据被修改的次数,任何对list的add/remove操作,都将导致modCount++. 在AbstractList中还有一个内部类Itr implements Iterator,Itr是一个list

windows server 2012中如何删除重复数据

实验名称:windows server2012实现重复数据删除 实验名称:实现重复数据删除 实验目标: 2 实现重复数据删除 实验环境:一台安装了WS2012操作系统的物理计算机,一台WS2012虚拟机(DC1). 任务1:安装'数据删除重复'角色. 1. 使用管理员帐户Administrator,登录到DC1. 2. 在任务栏,单击'服务器管理器'图标 . 3. 在'服务器管理器'窗口,单击'管理',在下拉菜单中单击'添加角色和功能'. 4. 在'选择安装类型'页面,选择'基于角色或功能的安装

重复数据删除在主存储中的应用

现如今,重复数据删除技术已经不再让人感到陌生,其价值也已经在备份领域获得了充分的体现,如何发挥重复数据删除技术的最大价值就成为厂商们又一个需要思考的问题.重复数据删除技术向主存储 领域的延伸(NetApp公司开了重复数据删除技术在主存储应用的先河),也让我们看到了厂商期待将这项 技术能够发挥更大的价值.在2009年SNW中国大会上,HIFN向大家展示了其BitWackr重复数据删除和数据 缩减技术,笔者也借此机会与HIFN公司中国区销售总监赵强先生就重复数据删除技术在主存储领域有何 价值进行了一

Windows Server 2012 R2中的VDI数据删除技术工作原理

  重复数据删除技术如何帮助工作负载在虚拟桌面工作?VDI重复数据删除有什么局限性吗? 终端虚拟化使用的技术如虚拟桌面基础结构(VDI)近年来引起了人们的关注,因为组织希望对终端实现集中管理并实施安全措施,同时减少对硬件的依赖.但存储是VDI部署的一个重要的限制,因为每个终端基本上都部署为一个虚拟机(VM).重复数据删除成了VDI中一个引人注目的好处,因为其显著降低了存储,极大地扩展了托管在每个服务器的桌面镜像数量,同时降低了企业级VDI部署所需的服务器数量. 传统的重复数据删除因为要打开/激活

R语言中如何删除数据对象

  R语言中如何删除数据对象 首先需要打开R studio,新建文件脚本,[File]--[New Script]. 然后会发现,global environment这里之前代码留下的数据集非常麻烦,清除方法如下: 首先,写入 rm(A),即可清除相应object的数据(rm=remove).对比即可发现,之前的object已经被清除了. 想要一了百了,全部清除的时候,则输入代码:rm(list=ls()). 这段代码的含义是:清除全部对象,即用ls()列出全部对象名,用一个list将全部对象装

框架-JAVA问题:删除数据库中数据的代码,测试不会报错,但实际什么都删不了

问题描述 JAVA问题:删除数据库中数据的代码,测试不会报错,但实际什么都删不了 这些操作做完后,数据库里的t_product表中,id=2的数据依然在,不是刷新的问题,刷新也还在 解决方案 为什么你的三个函数保存.修改.删除方法调用sql的时候都没有传递sql参数值呢? 解决方案二: 调用mapper里面的sql代码的时候,把要删除的id传进去了吗?不应该是sqlsession.delete("",参数);吗? 解决方案三: 参数没带.sqlsession.delect带上id 解决

c#中如何删除csv文件中除表头以外的数据

问题描述 c#中如何删除csv文件中除表头以外的数据 我想实现这样的动作,就是在每次向csv文件写数据的时候,都先把csv文件内的内容清空,但是要保留csv的表头.不知道有没有比较方便的做法? 解决方案 先用 StreamReader.ReadLine() 把第一行读到变量中.然后用覆盖的方式写第一行.写后续的数据. 又:数据多少列都确定了,表头不也确定的,直接写就行了. 解决方案二: 你可以简单的就是删除文件从第二行开始的内容 解决方案三: 按你的意思,你是搞1个csv然后丢1个. 那你在写第

arcengine-在Arcengine+C#中如何利用dataGridView来删除、更新SHP中数据

问题描述 在Arcengine+C#中如何利用dataGridView来删除.更新SHP中数据 在Arcengine+C#中,实现查询的功能,并且查询结果显示在dataGridView中,如何将选中的dataGridView的数据删除.更新,同时删除.更新SHP中的数据

vb.net中如何删除一条数据

问题描述 用vb.net链接了数据库,然后选中一条数据,按删除的按钮,删除这条数据,这个按钮的代买如何编写?还有,如何得到我选中的数据是第几条?谢谢 解决方案 解决方案二:读入数据时加入ID列,选中记录时,记下ID的值,删除时就方便了DeleteTableWhereid=解决方案三:DataTable.rows(datagrid1.currentcell.rownumber).deleteSqlDataAdapter.update(Dataset1.datatable)解决方案四:排序后使用ID