最近遇到這樣一個問題,要刪除一個集合中的某個元素,該怎么解決?
我自己寫了兩段代碼來刪除,都報了一個錯java.util.ConcurrentModificationException;為了讓更多可能沒注意到這個點的程序猿注意一下,我在這里分享下~
先看代碼

1 package com.zwt1234; 2 3 import java.util.HashSet; 4 import java.util.Iterator; 5 import java.util.Set; 6 7 public class IteratorTest { 8 public static void main(String[] args) { 9 Set<Object> s = new HashSet<Object>(0); 10 s.add(new Man("小明", 12)); 11 s.add(new Man("小李", 15)); 12 s.add(new Man("小華", 21)); 13 validateIterator(s); 14 // validateForeach(s); 15 } 16 17 /** 18 * 驗證Iterator接口的方法 19 * iterator進入循環后,相當於線程上了一把鎖,誰都不讓進,只能用iterator自己的對象操作數據 20 * 因此下面用s.remove(man)是,程序報錯 21 * @param s 22 */ 23 public static void validateIterator(Set<Object> s) { 24 Iterator<Object> iter = s.iterator(); 25 while (iter.hasNext()) { 26 Man man = (Man)iter.next(); 27 System.out.println(man); 28 if (man.name.equals("小李")) { 29 iter.remove(); 30 // s.remove(man);//此時程序報錯java.util.ConcurrentModificationException 31 } 32 } 33 System.out.println("------------------------"); 34 /* 35 * 執行上面刪除操作后重新打印s集合中元素,印證操作 36 */ 37 iter = s.iterator(); 38 while (iter.hasNext()) { 39 System.out.println(iter.next()); 40 } 41 } 42 43 /** 44 * 驗證foreach循環 45 * foreach循環相對iterator在查詢上面更加方便了,因為代碼量少了; 46 * 但是在歲數據操作上面比不過iterator 47 * @param s 48 */ 49 public static void validateForeach(Set<Object> s) { 50 for (Object obj:s) { 51 Man man = (Man)obj; 52 System.out.println(man); 53 if (man.name.equals("小李")) { 54 s.remove(man);//這里同樣是不讓刪除的,因為foreach循環底層就是用的iterator的實現方式 55 } 56 } 57 } 58 } 59 60 class Man { 61 String name; 62 int age; 63 64 Man(String name, int age) { 65 this.name = name; 66 this.age = age; 67 } 68 69 @Override 70 public String toString() { 71 return "Man [name=" + name + ", age=" + age + "]"; 72 } 73 }
下面我們來分析下我們這段代碼
1.首先我用,Iterator來實現的刪除,開始的時候,在遍歷到存入的對象名為小李的時候,我就讓這個對象,在Set集合s中刪除,在if語句里面,面對2個問題,集合s有給我們提供一個remove()方法,還有iterator也給我們提供了一個remove()方法,我們用哪個?
最開始的時候我選用的是Set集合給的方法,可是在運行的時候,結果就報錯了,而改用iterator提供的方法是可以正確運行的,正常刪除了我所需要刪除的對象。
結果總結:說明在使用iterator迭代器的時候,我們需要刪除集合中數據,使用的應該是Iterator的remove()方法,因為使用iterator的時候,就相當於給線程給資源上了一把鎖,只有iterator本身可以去刪除數據,而集合線程是無法在iterator占用資源的時候對資源進行刪除的。
2.同樣的foreach增強for循環的實現刪除的時候,我也去實現了下。
因為foreach循環沒有給我們提供remove()方法,因此我們直接使用Set集合里面給我們提供的刪除方法,發現也是會報和iterator同樣的錯誤,因此,證明foreach循環是不適合進行數據的刪除的。
(對於上面的代碼操作結果,就請大家copy一下,直接運行就能查看結果了,這里我就不展示了)
3.最后總結:①相比於foreach,迭代器iterator的使用略顯繁瑣;
②相比於foreach,迭代器iterato在對數據的操控顯然比foreach要靈活。
最后的最后,上面的總結知識博主自己的個人見解,有不周到的地方,或者錯誤的地方,請大家指正,謝謝~