集合架構之——迭代器並發修改異常ConcurrentModificationException

來源:互聯網
上載者:User

標籤: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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.