2011-06-07 41 views
36

ArrayList的列表迭代器確實實現了remove方法,但是我得到以下異常拋出: UnsupportedOperationException java.util.AbstractList.remove(AbstractList.java:144)AbstractList.remove()在ArrayList上操作時UnsupportedOperationException

這段代碼:

protected void removeZeroLengthStringsFrom(List<String> stringList) 
{ 
    ListIterator<String> iter = stringList.listIterator(); 
    String s; 
    while (iter.hasNext()) 
    { 
     s = iter.next(); 
     if (s.length() == 0) 
     { 
      iter.remove(); 
     } 
    } 
} 

缺少什麼我在這裏?我已經證實我通過的List<String>確實是ArrayList<String>

謝謝!

+0

是不止一個線程在同一個'List '上運行? – 2011-06-07 02:42:25

+0

我建議你驗證'stringList'的運行時類型是_really_類型的java.util.ArrayList。我懷疑你可能有一個'Vector'或'Stack'或'ArrayList'來自一些不會覆蓋'remove(int)'的包。 – 2011-06-07 02:55:44

+0

你是如何驗證它的?你是否直接檢查'removeZeroLengthStringsFrom()'內的'stringList.getClass()'等等? – QuantumMechanic 2011-06-07 02:56:16

回答

113

我想你可能會使用Arrays實用程序獲取您傳遞到該方法的List。該對象的確屬於ArrayList類型,但它的編號爲java.util.Arrays.ArrayList,而不是java.util.ArrayList

java.util.Arrays.ArrayList版本是不可變的,它的remove()方法沒有被覆蓋。因此,它遵循remove()AbstractList實現,該實現拋出UnsupportedOperationException

+0

這是什麼解決方案?! – Exceptional 2013-10-12 11:54:33

+25

解決方案將如下所示:new ArrayList <>(Arrays.asList(「a」,「b」,「c」)) – Kong 2013-10-24 21:11:28

+1

有兩種可能的解決方案。第一,正如Kong暗示的那樣,製作一個不可變ArrayList的副本並將其傳入。第二個,也是更可取的(在我看來),解決方案是重寫'remove ...'以返回一個List並構造一個新的該方法中的可變列表,將其返回給調用者。這個解決方案並不總是合理的(例如,如果你被鉤入了一個你不能修改的框架),但O(n)(迭代)比O(2n)(複製然後迭代)略好。 – 2013-11-07 00:46:28

2

我懷疑你正在傳遞一個ArrayList,因爲ArrayList迭代器上的remove方法不會引發該異常。

我猜你正在傳遞一個ArrayList的用戶派生類,它的迭代器在刪除時拋出異常。

public void remove() { 
    if (lastRet == -1) 
    throw new IllegalStateException(); 
     checkForComodification(); 

    try { 
    AbstractList.this.remove(lastRet); 
    if (lastRet < cursor) 
     cursor--; 
    lastRet = -1; 
    expectedModCount = modCount; 
    } catch (IndexOutOfBoundsException e) { 
    throw new ConcurrentModificationException(); 
    } 
}