对 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<String>
确实是ArrayList<String>
。
谢谢!
【问题讨论】:
是否有多个线程在同一个List<String>
上运行?
我建议您验证stringList
的运行时类型真的 属于java.util.ArrayList 类型。我怀疑你可能有来自某些不同包的Vector
或Stack
或ArrayList
,它们不会覆盖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的主要内容,如果未能解决你的问题,请参考以下文章