[英]Java: Why does calling `remove()` on a List throw UnsupportedOperation exception?
出於某種原因,我使用以下代碼獲得UnsupportedOpeationException
。 在調試器中檢查它,看起來我正在調用remove()
on的對象是一個列表。
// 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)
為什么會這樣?
您收到的List
的底層實現很可能是固定長度的,例如由Arrays#asList
創建的Arrays#asList
。
如果您要從List中刪除項目,那么您應該使用ListIterator,而不是使用for-each循環來遍歷列表,而是使用ListIterator,它以安全的方式支持remove()(即不會在列表或指向無處的索引)。
實現Collection接口的類是可選的,允許刪除對象(請參閱Collection#remove()
這是一個可選操作)。 如javadoc中所述,它會拋出
UnsupportedOperationException
- 如果此集合不支持remove
操作
在這種情況下你很可能(例如,如果你的集合包含由Jeffrey指出的Arrays.asList
返回的列表)。
可能是您在集合中傳遞的列表是從AbstractList
派生的,並且不實現(支持) remove()
方法?
此外,對於在HashMap位置映射的所有列表對象, location
似乎總是映射到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循環編寫自己的實用程序方法,以便在關鍵時執行此操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.