出于某种原因,我正在使用以下代码获得UnsupportedOpeationException
。在调试器中检查它,看起来我正在调用的对象remove()
是一个列表。
// to optimize, remove totalSize. After taking an item from lowest, if lowest is empty, remove it from `lists`
// lists are sorted to begin with
public static <T extends Comparable<? super T>> List<T> merge(Set<List<T>> lists) {
List<T> result = new ArrayList<T>();
HashMap<List<T>, Integer> location = new HashMap<List<T>, Integer>();
int totalSize = 0; // every element in the set
for (List<T> l : lists) {
location.put(l, 0);
totalSize += l.size();
}
boolean first;
List<T> lowest = lists.iterator().next(); // the list with the lowest item to add
int index;
while (result.size() < totalSize) { // while we still have something to add
first = true;
for (List<T> l : lists) {
if (! l.isEmpty()) {
if (first) {
lowest = l;
}
else if (l.get(location.get(l)).compareTo(lowest.get(location.get(lowest))) <= 0) {
lowest = l;
}
}
}
index = location.get(lowest);
result.add(lowest.get(index));
lowest.remove(index); //problem here
}
return result;
}
例外:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(Unknown Source)
at interview.questions.MergeLists.merge(MergeLists.java:72)
at interview.questions.MergeLists.main(MergeLists.java:32)
为什么会这样?
答案 0 :(得分:19)
您收到的List
的基础实现很可能是固定长度的,例如由Arrays#asList
创建的实现。
答案 1 :(得分:4)
如果查看API docs for the List interface,您会看到其中一些是“可选操作”。这意味着允许具体类抛出UnsupportedOperationException。
例如,如果列表已转换为unmodifiable list,则无法允许删除操作实际删除某些内容(或列表将被修改)。
所以对于Set&lt;列表与LT;&GT;&GT;部分代码中的一个或多个列表不允许您从中删除。
答案 2 :(得分:2)
如果要从List中删除项目,而不是使用for-each循环遍历列表,则应该使用ListIterator,它以安全的方式支持remove()(即不离开列表中的孔或指向无处的索引。
答案 3 :(得分:1)
实现Collection接口的类是可选的,允许删除对象(参见Collection#remove()
这是一个可选操作)。正如javadoc中所述,它会抛出
UnsupportedOperationException
- 如果此集合不支持remove
操作
在这种情况下你很可能(例如,如果你的集合包含由Jeffrey指出的Arrays.asList
返回的列表)。
答案 4 :(得分:0)
您在集合中传递的列表是否来自AbstractList
并且未实现(支持)remove()
方法?
此外,对于在HashMap位置映射的所有列表对象,location
似乎总是映射到0
?
答案 5 :(得分:0)
Collection接口中的remove()方法显式指定为可选操作:
remove(Object o)
Removes a single instance of the specified element from this collection, if it is present (optional operation).
列表不必支持。事实上,它没有明确的语义。列表不适用于那种随机访问。您可以获得例外,而不是提供可能效率低下或不准确的默认实现。
如果关键,可以使用for-each循环编写自己的实用程序方法。