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

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

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

瀏覽:51日期: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
相關文章:
主站蜘蛛池模板: 网站建设-网站制作-网站设计-网站开发定制公司-网站SEO优化推广-咏熠软件 | 识禅_对禅的了解,从这里开始 | 淄博不锈钢,淄博不锈钢管,淄博不锈钢板-山东振远合金科技有限公司 | 上海单片机培训|重庆曙海培训分支机构—CortexM3+uC/OS培训班,北京linux培训,Windows驱动开发培训|上海IC版图设计,西安linux培训,北京汽车电子EMC培训,ARM培训,MTK培训,Android培训 | 股指期货-期货开户-交易手续费佣金加1分-保证金低-期货公司排名靠前-万利信息开户 | 意大利Frascold/富士豪压缩机_富士豪半封闭压缩机_富士豪活塞压缩机_富士豪螺杆压缩机 | 昆明化妆培训-纹绣美甲-美容美牙培训-昆明博澜培训学校 | Safety light curtain|Belt Sway Switches|Pull Rope Switch|ultrasonic flaw detector-Shandong Zhuoxin Machinery Co., Ltd | 食品无尘净化车间,食品罐装净化车间,净化车间配套风淋室-青岛旭恒洁净技术有限公司 | 游动电流仪-流通式浊度分析仪-杰普仪器(上海)有限公司 | 玄米影院| 西安中国国际旅行社(西安国旅)| 北京网站建设首页,做网站选【优站网】,专注北京网站建设,北京网站推广,天津网站建设,天津网站推广,小程序,手机APP的开发。 | 浴室柜-浴室镜厂家-YINAISI · 意大利设计师品牌 | 咿耐斯 |-浙江台州市丰源卫浴有限公司 | 四合院设计_四合院装修_四合院会所设计-四合院古建设计与建造中心1 | Eiafans.com_环评爱好者 环评网|环评论坛|环评报告公示网|竣工环保验收公示网|环保验收报告公示网|环保自主验收公示|环评公示网|环保公示网|注册环评工程师|环境影响评价|环评师|规划环评|环评报告|环评考试网|环评论坛 - Powered by Discuz! | 定硫仪,量热仪,工业分析仪,马弗炉,煤炭化验设备厂家,煤质化验仪器,焦炭化验设备鹤壁大德煤质工业分析仪,氟氯测定仪 | 齿轮减速马达一体式_蜗轮蜗杆减速机配电机-德国BOSERL齿轮减速电动机生产厂家 | 单柱拉力机-橡胶冲片机-哑铃裁刀-江都轩宇试验机械厂 | 桥架-槽式电缆桥架-镀锌桥架-托盘式桥架 - 上海亮族电缆桥架制造有限公司 | 福兰德PVC地板|PVC塑胶地板|PVC运动地板|PVC商用地板-中国弹性地板系统专业解决方案领先供应商! 福建成考网-福建成人高考网 | 一体化隔油提升设备-餐饮油水分离器-餐厨垃圾处理设备-隔油池-盐城金球环保产业发展有限公司 | 英语词典_成语词典_日语词典_法语词典_在线词典网 | 磁棒电感生产厂家-电感器厂家-电感定制-贴片功率电感供应商-棒形电感生产厂家-苏州谷景电子有限公司 | 艺术漆十大品牌_艺术涂料加盟代理_蒙太奇艺术涂料厂家品牌|艺术漆|微水泥|硅藻泥|乳胶漆 | 江苏皓越真空设备有限公司| 蒜肠网-动漫,二次元,COSPLAY,漫展以及收藏型模型,手办,玩具的新媒体.(原变形金刚变迷TF圈) | 挖掘机挖斗和铲斗生产厂家选择徐州崛起机械制造有限公司 | 在线钠离子分析仪-硅酸根离子浓度测定仪-油液水分测定仪价格-北京时代新维测控设备有限公司 | 沥青车辙成型机-车托式混凝土取芯机-混凝土塑料试模|鑫高仪器 | 氧氮氢联合测定仪-联测仪-氧氮氢元素分析仪-江苏品彦光电 | 酒吧霸屏软件_酒吧霸屏系统,酒吧微上墙,夜场霸屏软件,酒吧点歌软件,酒吧互动游戏,酒吧大屏幕软件系统下载 | 南京展台搭建-南京展会设计-南京展览设计公司-南京展厅展示设计-南京汇雅展览工程有限公司 | 碳纤维布-植筋胶-灌缝胶-固特嘉加固材料公司| ★店家乐|服装销售管理软件|服装店收银系统|内衣店鞋店进销存软件|连锁店管理软件|收银软件手机版|会员管理系统-手机版,云版,App | 热缩管切管机-超声波切带机-织带切带机-无纺布切布机-深圳市宸兴业科技有限公司 | 苹果售后维修点查询,苹果iPhone授权售后维修服务中心 – 修果网 拼装地板,悬浮地板厂家,悬浮式拼装运动地板-石家庄博超地板科技有限公司 | 冷水机,风冷冷水机,水冷冷水机,螺杆冷水机专业制造商-上海祝松机械有限公司 | ALC墙板_ALC轻质隔墙板_隔音防火墙板_轻质隔墙材料-湖北博悦佳 | 液氮罐(生物液氮罐)百科-无锡爱思科| 无味渗透剂,泡沫抑尘剂,烷基糖苷-威海威能化工有限公司 |