Java: Why does calling `remove ()` on a List throw an UnsupportedOperation exception?

For some reason, I get an UnsupportedOpeationException with the following code. Looking at it in the debugger, it looks like an object that I call remove() on - this is a list.

 // 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; } 

An exception:

 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) 

Why is this happening?

+4
source share
6 answers

It is possible that the underlying List implementation you received is a fixed length, such as that created by Arrays#asList .

+19
source

If you look at the docs API for the List interface , you will see that some of them are “optional operations”. This means that a particular class is allowed to throw an UnsupportedOperationException.

If, for example, the List was converted to an unmodifiable list , it could not allow the delete operation to actually delete anything (or the list will be changed).

So, for Set <List <→ part of the code, one or more lists does not allow you to remove from it.

+4
source

If you intend to remove items from the list, instead of using a for loop for each iteration through the list, you should use a ListIterator that supports remove () in a safe way (that is, without leaving a hole in the list or a pointer pointing to nowhere).

+2
source

Optional for a class that implements the Collection interface to allow the removal of objects (see Collection#remove() , which is an optional operation), As stated in javadoc, it throws

UnsupportedOperationException - if the remove operation is not supported by this collection

Probably in this case (for example, if your set contains the list returned by Arrays.asList , as pointed out by Jeffrey).

+1
source

Could it be that the lists you pass in the set are derived from AbstractList and do not implement (support) the remove() method?

Also, does it seem that location always maps to 0 for the entire list object that appears in the HashMap location?

0
source

The remove () method in the Collection interface is explicitly specified as an optional operation:

 remove(Object o) Removes a single instance of the specified element from this collection, if it is present (optional operation). 

Lists should not support. In fact, for him there is no clear semantics. Lists are not intended for this kind of random access. Instead of providing some standard implementation that may be inefficient or inaccurate, you get an exception.

You can write your own utility method with a for-each loop to do this if it matters.

0
source

All Articles