对 ArrayList 进行操作时,AbstractList.remove() 中出现 UnsupportedOperationException

Posted

技术标签:

【中文标题】对 ArrayList 进行操作时,AbstractList.remove() 中出现 UnsupportedOperationException【英文标题】:UnsupportedOperationException in AbstractList.remove() when operating on ArrayList 【发布时间】:2011-09-09 17:56:24 【问题描述】:

ArrayList 的列表迭代器确实实现了 remove 方法,但是,我得到了以下异常:

UnsupportedOperationException at java.util.AbstractList.remove(AbstractList.java:144)

通过此代码:

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&lt;String&gt;确实是ArrayList&lt;String&gt;

谢谢!

【问题讨论】:

是否有多个线程在同一个List&lt;String&gt;上运行? 我建议您验证stringList 的运行时类型真的 属于java.util.ArrayList 类型。我怀疑你可能有来自某些不同包的VectorStackArrayList,它们不会覆盖remove(int) 你是如何验证的?您是否直接检查了removeZeroLengthStringsFrom() 内的stringList.getClass() 等? 【参考方案1】:

我认为您可能正在使用Arrays 实用程序来获取您传递给该方法的List。该对象确实是ArrayList 类型,但它是java.util.Arrays.ArrayList,而不是java.util.ArrayList

java.util.Arrays.ArrayList 版本是不可变的,其remove() 方法未被覆盖。因此,它遵循remove()AbstractList 实现,它会抛出UnsupportedOperationException

【讨论】:

解决办法是什么?!! 解决方案是这样的:new ArrayList(Arrays.asList("a", "b", "c")) 有两种可能的解决方案。正如 Kong 所暗示的,第一个是复制不可变的 ArrayList 并将其传入。第二个也是更可取的(在我看来)解决方案是重写 remove... 以返回一个 List 并在其中构造一个新的可变 List方法,将其返回给调用者。该解决方案并不总是合理的(例如,如果您陷入无法修改的框架),但 O(n)(迭代)略好于 O(2n)(复制然后迭代)。 【参考方案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();
    

【讨论】:

以上是关于对 ArrayList 进行操作时,AbstractList.remove() 中出现 UnsupportedOperationException的主要内容,如果未能解决你的问题,请参考以下文章

有两个ArrayList集合,存储队伍中的多个成员姓名,使用Stream方式,对以下步骤进行操作

ArrayList和LinkedList

ArrayList和LinkedList的区别。

ArrayList和LinkedList的区别。

ArrayList和LinkedList的区别。

请说一下 ArrayList,Vector, LinkedList的区别