須要在一個Set類型的集合中刪除知足條件的對象,這時想固然地想到直接調用Set的remove(Object o)方法將指定的對象刪除便可,測試代碼: public class Test { public static void main(String[] args) { User user1 = new User(); user1.setId(1); user1.setName("zhangsan"); User user2 = new User(); user2.setId(2); user2.setName("lisi"); Set userSet = new HashSet(); userSet.add(user1); userSet.add(user2); for (Iterator it = userSet.iterator(); it.hasNext();) { User user = (User) it.next(); if (user.getId() == 1) { userSet.remove(user); } if (user.getId() == 2) { user.setName("zhangsan"); } } for(Iterator it = userSet.iterator(); it.hasNext(); ) { User user = (User) it.next(); System.out.println(user.getId() + "=>" + user.getName()); } } } 但運行程序的時候,卻發現出錯了: Exception in thread "main" java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextEntry(Unknown Source) at java.util.HashMap$KeyIterator.next(Unknown Source) at test.Test.main(Test.java:23) 從API中能夠看到List等Collection的實現並無同步化,若是在多 線程應用程序中出現同時訪問,並且出現修改操做的時候都要求外部操做同步化;調用Iterator操做得到的Iterator對象在多線程修改Set的時 候也自動失效,並拋出java.util.ConcurrentModificationException。這種實現機制是fail-fast,對外部 的修改並不能提供任何保證。 網上查找的關於Iterator的工做機制。Iterator是工做在一個獨立的線程中,而且擁有一個 mutex鎖,就是說Iterator在工做的時候,是不容許被迭代的對象被改變的。Iterator被建立的時候,創建了一個內存索引表(單鏈表),這 個索引表指向原來的對象,當原來的對象數量改變的時候,這個索引表的內容沒有同步改變,因此當索引指針往下移動的時候,便找不到要迭代的對象,因而產生錯 誤。List、Set等是動態的,可變對象數量的數據結構,可是Iterator則是單向不可變,只能順序讀取,不能逆序操做的數據結構,當 Iterator指向的原始數據發生變化時,Iterator本身就迷失了方向。 如何才能知足需求呢,須要再定義一個List,用來保存須要刪除的對象: List delList = new ArrayList(); 最後只須要調用集合的removeAll(Collection con)方法就能夠了。 public class Test { public static void main(String[] args) { boolean flag = false; User user1 = new User(); user1.setId(1); user1.setName("shangsan"); User user2 = new User(); user2.setId(2); user2.setName("lisi"); Set userSet = new HashSet(); userSet.add(user1); userSet.add(user2); List delList = new ArrayList(); for (Iterator it = userSet.iterator(); it.hasNext();) { User user = (User) it.next(); if (user.getId() == 1) { delList.add(user); } if (user.getId() == 2) { user.setName("zhangsan"); } } userSet.removeAll(delList); for(Iterator it = userSet.iterator(); it.hasNext(); ) { User user = (User) it.next(); System.out.println(user.getId() + "=>" + user.getName()); } } }