AbstractList.remove()在ArrayList上操作时UnsupportedOperationException

问题描述:

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

我想你可能会使用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

我怀疑你正在传递一个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(); 
    } 
}