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.
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]);
}
}
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)
.
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));
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));
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.
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));
Why java.lang.UnsupportedOperationException thrown when process list
Arrays.asList("One","Two","Three","Four")
returns a constant size List
backed by an array, so you can't add elements to it.
Use
List<String> strs = new ArrayList<>(Arrays.asList("One","Two","Three","Four"));
instead.
Related Topics
Hibernate: Different Object with the Same Identifier Value Was Already Associated with the Session
Compile Code Using Javafx 2.0 (Using Command Line)
Detect Touch Press VS Long Press VS Movement
How to Use Interface to Communicate Between Two Activities
Java Heap Terminology: Young, Old and Permanent Generations
Nullpointerexception in Java with No Stacktrace
Error: Unable to Load Installed Packages Just Now
How to Make Rjava Use the Newer Version of Java on Osx
Why Does "String".Getbytes() Work Different According to the Operation System
Trying to Locate a Leak! What Does Anon Mean for Pmap
Running Java Program from Command Line Linux
Spring JSON Request Getting 406 (Not Acceptable)
Does Python Have an Equivalent to Java Class.Forname()
How to View/Change Socket Connection Timeout on Linux
Can't Make Jdbc Connection to MySQL (Using Java, Intellij, and Linux)
How to Include Raw JSON in an Object Using Jackson
How to Load a Resource from Web-Inf Directory of a Web Archive
Where Does Java's String Constant Pool Live, the Heap or the Stack