电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

java迭代器移除元素出現并發修改異常的原因及解決

瀏覽:53日期:2022-08-20 09:06:54

迭代器(Iterator的對象)主要用于遍歷集合,體現的就是迭代器模式。

Iterator接口定義了以下四種方法。

boolean hasNext():如果集合還沒遍歷完就返回true。

Object next():返回集合里的下一個元素。

void remove():刪除集合里上一次next方法返回的元素。

void forEachRemaining(Consumer action):這是java8新增的默認方法,可用Lambda表達式遍歷數組。

使用迭代器遍歷元素時不能不能通過Collection接口中的remove方法刪除元素,只能用Interator的remove方法刪除元素,下面根據案例和源代碼分析原因。

public class InteratorTest { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add('zhangsan'); list.add('lisi'); list.add('wangwu'); list.add('zhaoliu'); Iterator<String> it = list.iterator(); while(it.hasNext()) { String str = it.next();//java.util.ConcurrentModificationException并發修改異常 System.out.println(str); if('lisi'.equals(str)) { list.remove(str); } } System.out.println(list); }}

并發修改異常: 當方法檢測到對象的并發修改,但不允許這種修改時,拋出此異常。例如,某個線程在 Collection 上進行迭代時,通常不允許另一個線性修改該 Collection(來自java API),從這里可以看出迭代器和集合是在不同線程里的。

查看資料知道了,迭代器其實在另外一個線程復制了一個一摸一樣的集合進行遍歷的。當用集合的remove方法刪除元素時,迭代器是不會知道的,所以就會拋出異常。

下面看源碼分析。

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]; }

而用迭代器的ramove方法刪除元素時,實際在底層還是用的集合的remove方法,所以迭代器和集合修改元素的次數一樣是不會出現異常的。

源碼如下:

public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet);//用的還是集合的remove方法 cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } }

并發修改異常出現的原因已經找到了。但是Arraylist迭代器會出現下面這種情況,當我們用集合刪除方法刪除倒數第二個元素時,并不會出現異常。

public class InteratorTest { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add('zhangsan'); list.add('lisi'); list.add('wangwu'); list.add('zhaoliu'); Iterator<String> it = list.iterator(); while(it.hasNext()) { String str = it.next();//不會出現并發修改異常 System.out.println(str); if('wangwu'.equals(str)) {//用集合Remove方法刪除倒數第二個元素 list.remove(str); } } System.out.println(list); }}

原因是這樣的,當while循環到第三次的時候也就是遍歷到“wangwu”時,這時候迭代器的cursor(游標相當于指針)變量值為2,集合元素個數為4。執行完it.next()方法后cursor值為3,接著刪除“wangwu”這個元素后,集合的size變成了3。當繼續第四次循環時現判斷hasNext()當cursor值和size值相等時返回false,所以不會執行while循環里面的語句,自然不會執行next()方法,所以時不會出現異常的。

public boolean hasNext() { return cursor != size;//根據上面的說法在循環第四次是返回的是false,不會執行循環里的的代碼 }

補充知識:java使用迭代器刪除元素_使用Java從地圖中刪除元素

關于從Java中的Map刪除元素的非常簡短的文章。 我們將專注于刪除多個元素,而忽略了您可以使用Map.remove刪除單個元素的Map.remove 。

以下Map將用于此帖子:

Map<Integer, String> map = new HashMap<>();map.put(1, 'value 1');map.put(2, 'value 2');map.put(3, 'value 3');map.put(4, 'value 4');map.put(5, 'value 5');

有幾種刪除元素的方法。 您可以手動遍歷代碼并將其刪除:

for(Iterator<Integer> iterator = map.keySet().iterator(); iterator.hasNext(); ) { Integer key = iterator.next(); if(key != 1) { iterator.remove(); }}

這是您無需訪問Java 8+即可執行的操作。 從Map刪除元素時,需要Iterator來防止ConcurrentModificationException 。

如果您確實有權使用Java(8+)的較新版本,則可以從以下選項中進行選擇:

// remove by valuemap.values().removeIf(value -> !value.contains('1'));// remove by keymap.keySet().removeIf(key -> key != 1);// remove by entry / combination of key + valuemap.entrySet().removeIf(entry -> entry.getKey() != 1);

removeIf是Collection可用的方法。 是的, Map本身不是Collection ,也無權訪問removeIf本身。

但是,通過使用: values , keySet或entrySet ,將返回Map內容的視圖。 該視圖實現Collection允許在其上調用removeIf 。

由values , keySet和entrySet返回的內容非常重要。

以下是JavaDoc的values摘錄:

* Returns a { this map. Collection} view of the values contained in * Returns a { @link Collection} view of the values contained in map. * The collection is backed by the map, so changes to the map are * reflected in the collection, and vice-versa. * * The collection supports element removal, which removes the corresponding * mapping from the map, via the { @code Iterator.remove}, * mapping from the map, via the { Iterator.remove}, * { @code Collection.remove}, { @code removeAll}, * { @code retainAll} and { @code clear} operations.

此JavaDoc解釋說,由values返回的Collection由Map支持,并且更改Collection或Map都會改變另一個。 我認為我無法解釋JavaDoc所說的內容,而不是那里已經寫的內容。因此,我現在將不再嘗試該部分。 我只顯示了values的文檔,但是當我說keySet和entrySet也都由Map的內容作為后盾時,您可以信任我。 如果您不相信我,可以自己閱讀文檔。

這也使用舊版 Java版本鏈接回第一個示例。 該文檔指定可以使用Iterator.remove 。 這是早先使用的。 此外, removeIf的實現與Iterator示例非常相似。 討論完之后,我不妨展示一下:

default boolean removeIf(Predicate<? super E> filter) { Objects.requireNonNull(filter); boolean removed = false; final Iterator<E> each = iterator(); while (each.hasNext()) { if (filter.test(each.next())) { each.remove(); removed = true; } } return removed;}

還有一些額外的東西。 但是,否則幾乎是相同的。

就是這樣。 除了讓我記住要告訴您的記住以外,沒有太多結論了:使用values , keySet或entrySet將提供對removeIf訪問,從而允許輕松刪除Map條目。

以上這篇java迭代器移除元素出現并發修改異常的原因及解決就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持好吧啦網。

標簽: Java
相關文章:
主站蜘蛛池模板: 英国公司注册-新加坡公司注册-香港公司开户-离岸公司账户-杭州商标注册-杭州优创企业 | 上海电子秤厂家,电子秤厂家价格,上海吊秤厂家,吊秤供应价格-上海佳宜电子科技有限公司 | 无锡市珂妮日用化妆品有限公司|珂妮日化官网|洗手液厂家 | 耐破强度测试仪-纸箱破裂强度试验机-济南三泉中石单品站 | 德国BOSCH电磁阀-德国HERION电磁阀-JOUCOMATIC电磁阀|乾拓百科 | 集菌仪_智能集菌仪_全封闭集菌仪_无菌检查集菌仪厂家-那艾 | 磁力加热搅拌器-多工位|大功率|数显恒温磁力搅拌器-司乐仪器官网 | 液压扳手-高品质液压扳手供应商 - 液压扳手, 液压扳手供应商, 德国进口液压拉马 | 单螺旋速冻机-双螺旋-流态化-隧道式-食品速冻机厂家-广州冰泉制冷 | 动物麻醉机-数显脑立体定位仪-北京易则佳科技有限公司 | 菲希尔X射线测厚仪-菲希尔库伦法测厚仪-无锡骏展仪器有限责任公司 | 脉冲除尘器,除尘器厂家-淄博机械 | 登车桥动力单元-非标液压泵站-非标液压系统-深圳市三好科技有限公司 | 模具ERP_模具管理系统_模具mes_模具进度管理_东莞市精纬软件有限公司 | 上海单片机培训|重庆曙海培训分支机构—CortexM3+uC/OS培训班,北京linux培训,Windows驱动开发培训|上海IC版图设计,西安linux培训,北京汽车电子EMC培训,ARM培训,MTK培训,Android培训 | 蜂窝块状沸石分子筛-吸附脱硫分子筛-萍乡市捷龙环保科技有限公司 | 蓝鹏测控平台 - 智慧车间系统 - 车间生产数据采集与分析系统 | 爱佩恒温恒湿测试箱|高低温实验箱|高低温冲击试验箱|冷热冲击试验箱-您身边的模拟环境试验设备技术专家-合作热线:400-6727-800-广东爱佩试验设备有限公司 | 医用空气消毒机-医用管路消毒机-工作服消毒柜-成都三康王 | 自恢复保险丝_贴片保险丝_力特保险丝_Littelfuse_可恢复保险丝供应商-秦晋电子 | 澳门精准正版免费大全,2025新澳门全年免费,新澳天天开奖免费资料大全最新,新澳2025今晚开奖资料,新澳马今天最快最新图库-首页-东莞市傲马网络科技有限公司 | 振动时效_振动时效仪_超声波冲击设备-济南驰奥机电设备有限公司 北京宣传片拍摄_产品宣传片拍摄_宣传片制作公司-现像传媒 | 深圳成考网-深圳成人高考报名网 深圳工程师职称评定条件及流程_深圳职称评审_职称评审-职称网 | 蒸汽热收缩机_蒸汽发生器_塑封机_包膜机_封切收缩机_热收缩包装机_真空机_全自动打包机_捆扎机_封箱机-东莞市中堡智能科技有限公司 | 沈阳庭院景观设计_私家花园_别墅庭院设计_阳台楼顶花园设计施工公司-【沈阳现代时园艺景观工程有限公司】 | 全自动端子机|刺破式端子压接机|全自动双头沾锡机|全自动插胶壳端子机-东莞市傅氏兄弟机械设备有限公司 | led太阳能路灯厂家价格_风光互补庭院灯_农村市政工程路灯-中山华可路灯品牌 | 砖机托板价格|免烧砖托板|空心砖托板厂家_山东宏升砖机托板厂 | 危废处理系统,水泥厂DCS集散控制系统,石灰窑设备自动化控制系统-淄博正展工控设备 | 全自动包衣机-无菌分装隔离器-浙江迦南科技股份有限公司 | 环氧乙烷灭菌器_压力蒸汽灭菌器_低温等离子过氧化氢灭菌器 _低温蒸汽甲醛灭菌器_清洗工作站_医用干燥柜_灭菌耗材-环氧乙烷灭菌器_脉动真空压力蒸汽灭菌器_低温等离子灭菌设备_河南省三强医疗器械有限责任公司 | 拼装地板,悬浮地板厂家,悬浮式拼装运动地板-石家庄博超地板科技有限公司 | 招商帮-一站式网络营销服务|互联网整合营销|网络推广代运营|信息流推广|招商帮企业招商好帮手|搜索营销推广|短视视频营销推广 | 不锈钢法兰-碳钢法兰-法兰盘生产加工厂家-[鼎捷峰]-不锈钢法兰-碳钢法兰-法兰盘生产加工厂家-[鼎捷峰] | 双工位钻铣攻牙机-转换工作台钻攻中心-钻铣攻牙机一体机-浙江利硕自动化设备有限公司 | 铝机箱_铝外壳加工_铝外壳厂家_CNC散热器加工-惠州市铂源五金制品有限公司 | QQ房产导航-免费收录优秀房地产网站_房地产信息网 | 在线浊度仪_悬浮物污泥浓度计_超声波泥位计_污泥界面仪_泥水界面仪-无锡蓝拓仪表科技有限公司 | 存包柜厂家_电子存包柜_超市存包柜_超市电子存包柜_自动存包柜-洛阳中星 | 双舌接地线-PC68数字式高阻计-ZC36|苏海百科 | 体检车_移动CT车_CT检查车_CT车_深圳市艾克瑞电气有限公司移动CT体检车厂家-深圳市艾克瑞电气有限公司 |