標籤:throw win move 情況 strong 寫代碼 odi void public
問題:
我有一個集合,如下,請問,我想判斷裡面有沒有”world”這個元素,如果有,我就添加一個”javaee”元素,請寫代碼實現。
使用普通迭代器出現的異常:
ConcurrentModificationException:當方法檢測到對象的並發修改,但不允許這種修改時,拋出此異常。
產生的原因:
迭代器是依賴於集合而存在的,在判斷成功後,集合的中新添加了元素,而迭代器卻不知道,所以就報錯了,這個錯叫並發修改異常。
其實這個問題描述的是:普通迭代器遍曆元素的時候,通過集合是不能修改元素的。
解決:
A:迭代器迭代元素,迭代器修改元素
元素是跟在剛才迭代的元素後面的。
B:集合遍曆元素,集合修改元素(普通for迴圈進行遍曆)
元素是在最後添加的。
1 import java.util.ArrayList; 2 import java.util.Iterator; 3 import java.util.List; 4 import java.util.ListIterator; 5 6 public class ListIteratorDemo2 { 7 public static void main(String[] args) { 8 // 建立List集合對象 9 List list = new ArrayList();10 // 添加元素11 list.add("hello");12 list.add("world");13 list.add("java");14 15 // 普通迭代器遍曆16 // Iterator it = list.iterator();17 // while (it.hasNext()) {18 // String s = (String) it.next();19 // if ("world".equals(s)) {20 // list.add("javaee"); //這裡報錯!!!!21 // }22 // }23 24 方式1:迭代器迭代元素,迭代器修改元素25 而Iterator迭代器卻沒有添加功能,所以我們使用其子介面ListIterator26 ListIterator lit = list.listIterator();27 while (lit.hasNext()) {28 String s = (String) lit.next();29 if ("world".equals(s)) {30 lit.add("javaee");31 }32 }33 34 方式2:集合遍曆元素,集合修改元素(普通for)35 for (int x = 0; x < list.size(); x++) {36 String s = (String) list.get(x);37 if ("world".equals(s)) {38 list.add("javaee");39 }40 }41 42 System.out.println("list:" + list);43 }44 }
另外,尤其值得注意的是此迭代器remove()方法的使用:從迭代器指向的 collection 中移除迭代器返回的最後一個元素(可選操作)。每次調用 next 只能調用一次此方法。如果進行迭代時用調用此方法(remove方法)之外的其他方式修改了該迭代器所指向的 collection,則迭代器的行為是不確定的。 介面設計人員在設計Iterator<T>介面的時候已經指出,在進行迭代時如果調用了除了迭代器的remove()方法修改了該迭代器所指向的collection,則會造成不確定的後果。具體出現什麼後果依迭代器的具體實現而定。針對這種不確定的後果可能出現的情況,在學習ArrayList時遇到了其中一種:迭代器拋出 ConcurrentModificationException異常。具體異常情況如下代碼所示:
1 import java.util.ArrayList; 2 import java.util.Collection; 3 import java.util.Iterator; 4 5 public class ItaratorTest { 6 7 public static void main(String[] args) { 8 Collection<String> list = new ArrayList<String>(); 9 list.add("Android");10 list.add("IOS");11 list.add("Windows Mobile");12 13 Iterator<String> iterator = list.iterator();14 while (iterator.hasNext()) {15 String lang = iterator.next();16 list.remove(lang);//will throw ConcurrentModificationException17 }18 }19 20 }
此段代碼在運行時會拋出ConcurrentModificationException異常,因為我們在迭代器運行期間沒有用iterator的remove()方法來刪除元素,而是使用ArrayList的 remove()方法改變了迭代器所指向的collection。這就違反了迭代器的設計原則,所以發生了異常。
總結:
- 在用迭代器Iterator遍曆collection時,如果要在遍曆期間修改collection,則必須通過Iterator/listIterator來實現,否則可能會發生“不確定的後果”。
集合架構之——迭代器並發修改異常ConcurrentModificationException