Remove() on List Created by Arrays.Aslist() Throws Unsupportedoperationexception

remove() on List created by Arrays.asList() throws UnsupportedOperationException

Arrays.asList returns a List wrapper around an array. This wrapper has a fixed size and is directly backed by the array, and as such calls to set will modify the array, and any other method that modifies the list will throw an UnsupportedOperationException.

To fix this, you have to create a new modifiable list by copying the wrapper list's contents. This is easy to do by using the ArrayList constructor that takes a Collection:

Collection c = new ArrayList(Arrays.asList(la));

Why do I get an UnsupportedOperationException when trying to remove an element from a List?

Quite a few problems with your code:

On Arrays.asList returning a fixed-size list

From the API:

Arrays.asList: Returns a fixed-size list backed by the specified array.

You can't add to it; you can't remove from it. You can't structurally modify the List.

Fix

Create a LinkedList, which supports faster remove.

List<String> list = new LinkedList<String>(Arrays.asList(split));

On split taking regex

From the API:

String.split(String regex): Splits this string around matches of the given regular expression.

| is a regex metacharacter; if you want to split on a literal |, you must escape it to \|, which as a Java string literal is "\\|".

Fix:

template.split("\\|")

On better algorithm

Instead of calling remove one at a time with random indices, it's better to generate enough random numbers in the range, and then traversing the List once with a listIterator(), calling remove() at appropriate indices. There are questions on stackoverflow on how to generate random but distinct numbers in a given range.

With this, your algorithm would be O(N).

Arrays.asList give UnsupportedOperationException

Arrays.asList returns a fixed size List backed by an array. Therefore remove and add are not supported. set is supported. You can look at this List as if it behaves exactly like an array. An array has a fixed length. You can't add or remove elements, but you can assign values to the indices of the array, which is equivalent to the set method of List. And you can sort an array.

Collections.sort(list) doesn't change the size of the List, so is can sort a fixed size list. All you need in order to sort a List is to swap elements of the List. For this purpose set(index,element) is sufficient.

All this information is found in the Javadoc of Arrays :

/**
* Returns a fixed-size list backed by the specified array. (Changes to
* the returned list "write through" to the array.) This method acts
* as bridge between array-based and collection-based APIs, in
* combination with {@link Collection#toArray}. The returned list is
* serializable and implements {@link RandomAccess}.
*
* <p>This method also provides a convenient way to create a fixed-size
* list initialized to contain several elements:
* <pre>
* List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
* </pre>
*
* @param a the array by which the list will be backed
* @return a list view of the specified array
*/
public static <T> List<T> asList(T... a)

And if you look at an implementation of Collections.sort, you see that it actually sorts an array. The only List method it requires that modified the List is set of the List's ListIterator, which calls the List's set(index,element) method.

public static <T extends Comparable<? super T>> void sort(List<T> list) {
Object[] a = list.toArray();
Arrays.sort(a);
ListIterator<T> i = list.listIterator();
for (int j=0; j<a.length; j++) {
i.next();
i.set((T)a[j]);
}
}

java.util.Arrays.asList when used with removeIf throws UnsupportedOperationException

java.util.Arrays.asList() produces a list from which it is impossible to remove elements, so it throws on a removal attempt.

You could wrap it with ArrayList:

List<Integer> ints = new java.util.ArrayList<>(java.util.Arrays.asList(1,20,20));

Update

Arrays.asList() returns return new ArrayList<>(a); where ArrayList is not java.util.ArrayList, but java.util.Arrays.ArrayList (internal class), which does not allow removal.

Why does List.remove(int) throw java.lang.UnsupportedOperationException?

You're using it on a List implementation returned by Arrays.asList(), which returns a fixed-length collection, therefore a remove is unsupported.

Unable to perform an operation on ArrayList

You cannot change the number of elements of the List (using add() or remove() or similar) returned by Arrays.asList (but it allows to change elements using .set()).

From the docs of Arrays.asList:

The returned list implements the optional Collection methods, except those that would change the size of the returned list. Those methods leave the list unchanged and throw UnsupportedOperationException.

Instead, you can create an ArrayList with the same elements:

List<Integer> klist= new ArrayList<>(Arrays.asList(10,20,30,40,50));

UnsupportedOperationException when trying to remove a list of items from another list

Arrays.asList returns Arrays.ArrayList, a List implementation that doesnt support the removal of elements. Use

List<Integer> validDates = new ArrayList<>(Arrays.asList(26,27,28,1,2,3,4));

UnsupportedOperationException when trying to remove from the list returned by Array.asList

Array.asList() wraps an array in the list interface. The list is still backed by the array. Arrays are a fixed size - they don't support adding or removing elements, so the wrapper can't either.

The docs don't make this as clear as they might, but they do say:

Returns a fixed-size list backed by the specified array.

The "fixed-size" bit should be a hint that you can't add or remove elements :)

Although there are other ways around this (other ways to create a new ArrayList from an array) without extra libraries, I'd personally recommend getting hold of the Google Collections Library (or Guava, when it's released). You can then use:

List<Integer> list = Lists.newArrayList(array);

The reason I'm suggesting this is that the GCL is a generally good thing, and well worth using.

As noted in comments, this takes a copy of the array; the list is not backed by the original array, and changes in either collection will not be seen in the other.



Related Topics



Leave a reply



Submit