2013-07-26 58 views
0

我有下面的示例java泛型代碼,我根據StackOverflow上的人的建議進行了修改。編譯正在進行。java泛型運行時error.java.util.ConcurrentModificationException

import java.util.*; 

public class GenericBox<T> 
{ 

     private List<T> tList; 
     private Iterator<T> itor; 

     public GenericBox() 
     { 
       tList = new ArrayList<T>(); 
       itor = tList.listIterator(); 
     } 

     public void insert(T element) 
     { 
       tList.add(element); 
     } 

     public T retrieve() 
     { 
       if(itor.hasNext()) 
       { 
         return itor.next(); 
       } 
       return null; 
     } 

     public static void main (String [] args) 
     { 

       GenericBox <String> strbox = new GenericBox<String>(); 
       GenericBox <String> intbox = new GenericBox<String>(); 

       strbox.insert(new String("karthik")); 
       strbox.insert(new String("kanchana")); 
       strbox.insert(new String("aditya")); 


       String s = strbox.retrieve(); 
       System.out.println(s); 

       s = strbox.retrieve(); 
       System.out.println(s); 

       s = strbox.retrieve(); 
       System.out.println(s); 
     } 
} 

我收到以下運行時錯誤。

Exception in thread "main" java.util.ConcurrentModificationException 
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819) 
    at java.util.ArrayList$Itr.next(ArrayList.java:791) 
    at GenericBox.retrieve(GenericBox.java:24) 
    at GenericBox.main(GenericBox.java:40) 

回答

5

這有什麼好做仿製藥,並一切做,你直接修改(以insert)集合,然後試圖用其插入之前創建一個迭代的事實。不要這樣做。

ArrayList文檔:

此類的iterator和listIterator方法返回的迭代器是快速失敗的:如果列表隨時結構上修改後的迭代器創建的,以任何方式,除了通過迭代器自己的remove或add方法,迭代器將拋出一個ConcurrentModificationException異常。因此,面對併發修改,迭代器快速而乾淨地失敗,而不是在將來某個未確定的時間冒着任意的,非確定性的行爲風險。

如果必須保持迭代器周圍,使用增加,而不是一個新值:

private ListIterator<T> itor; // Not just Iterator<T>; you need the add method 

public void insert(T element) 
{ 
    itor.add(element); 
} 

這將是最好不要讓迭代器周圍雖然 - 這是非常很少有人使用迭代器而不是直接循環。

1

你會得到這個異常,因爲列表已經在創建迭代器和它的用法之間被修改了。當您實際想要迭代列表時,您應該僅調用iterator()。之前沒有。而且你不應該將迭代器存儲在實例字段中。只在局部變量中。

+0

你是說迭代器不應該是一個實例變量。每一個方法應該創建一個自己的構造函數的副本?這是一種被接受/推薦的編碼習慣嗎? – liv2hak

+1

迭代器只能使用一次。在使用時您無法修改集合。當你想迭代時,你需要一個新的迭代器到集合中,這很簡單。大多數情況下,你甚至不需要迭代器:for-each循環會爲你創建一個:'for(T element:tList)...' –