This question already has answers here:
Why do I get an UnsupportedOperationException when trying to remove an element from a List?
(17 answers)
java.lang.UnsupportedOperationException adding to a list [duplicate]
(2 answers)
Arrays.asList give UnsupportedOperationException [duplicate]
(2 answers)
UnsupportedOperationException at java.util.AbstractList.add
(7 answers)
Why i can't add element using list reference which returned by method [duplicate]
(3 answers)
Closed 1 year ago.
My intention is to make a shallow clone of the ArrayList but before that i am facing an issue while modifying the list.
Adding the another element in the list giving
UnsupportedOrderException
WHY?
class Mine implements Cloneable {
public List<Integer> list;
Mine(List<Integer> mylist) {
this.list = mylist;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Demo {
public static void main(String[] args) throws CloneNotSupportedException {
List<Integer> klist= Arrays.asList(10,20,30,40,50);
Mine m1=new Mine(klist);
m1.list.add(11); // <- why i am unable to add to the list
Mine m2= (Mine) m1.clone();
}
}
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));
Arrays.asList() returns a List<T> implementation that is backed by the original array. (Changed to the array can be seen via the list and vice versa.)
Arrays have a fixed size in Java, therefore the list returned by Arrays.asList has to have a fixed size as well - you can't add to it, and you can't remove from it.
You can create a new ArrayList<T> instead, which creates a copy of the array:
List<Integer> list = new ArrayList<>(Arrays.asList(...));
Although ArrayList is still backed by an array, it will create a new array where necessary. The array is an implementation detail, rather than the list being a "view" over an existing array as is returned by Arrays.asList.
In addition to #dan1st's answer (and now #JonSkeet as well), you can create your own asList() method to return a mutable List<T>:
static public List<T> asMutableList(T ... elts) {
List<T> lst = new ArrayList<>(elts.length);
for (T el : elts) {
lst.add(el);
}
return lst;
}
Related
This question already has answers here:
CopiesList.addAll method throws UnsupportedOperationException
(2 answers)
Closed 3 years ago.
Im trying to create an 8 element list [0,0,0,0,0,0,0,0] and then change the value of given index using the .set method. However the code raises an exception.
import java.util.*;
public class HQ {
public static void main(String[] arg)
{
List<Integer> quantity= Collections.nCopies(8, 0);
quantity.set(0,1);
}
}
I thought it would change the first element of quantity to be 1 and leave the rest as 0.
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.set(AbstractList.java:132)
at HQ.main(HQ.java:10)
Collections.nCopies will return immutable list, so you can't modify it
Returns an immutable list consisting of n copies of the specified object. The newly allocated data object is tiny (it contains a single reference to the data object). This method is useful in combination with the List.addAll method to grow lists. The returned list is serializable.
You can use stream to create mutable list with n copies
List<Integer> ints = IntStream.range(0, 7).map(i -> 0).boxed().collect(Collectors.toList());
or just convert immutable list into mutable
List<Integer> quantity1= Collections.nCopies(8, 0);
List<Integer> quantity = new ArrayList<Integer>(quantity1);
This question already has an answer here:
java.util.Arrays.asList when used with removeIf throws UnsupportedOperationException
(1 answer)
Closed 4 years ago.
Whenever I try to remove an element from a List using list.removeIf(condition) it throws UnsupportedOperationException:
public class Test
{
public static void main(final String[] args)
{
String[] stringArray = new String[]{"A","B","C","D"};
List<String> stringList = Arrays.asList(stringArray);
stringList.forEach(System.out::println);
stringList.removeIf((String string) -> string.equals("B"));
stringList.forEach(System.out::println);
}
}
Why is it not working?
Arrays.asList returns a fixed sized List - backed by the array you pass in - so, just as you can't remove (or add) elements from an array, you can't remove (or add) elements from the List.
Use a java.util.ArrayList in order to be able to remove elements:
List<String> stringList = new ArrayList<>(Arrays.asList(stringArray));
Array.asList method returns an ArrayList of type java.util.Arrays.ArrayList (which is read only and fixed size) and not the classic java.util.ArrayList (resizable and item-removable)
This question already has answers here:
Easiest way to convert a List to a Set in Java
(17 answers)
Closed 6 years ago.
I need to create method that will return permutations of arraylist. I used this method but it returns List<List<T>> and i need to get Set<Set<T>> type. Can anyone help me achieve this?
EDIT: I have tried:
public Set<Set<T>> permute() {
List<List<T>> tmp = generatePerm(this);
Set<Set<T>> tmpSet = new HashSet<>();
for (List<T> el : tmp){
tmpSet.add(new HashSet<T>(el));
}
return tmpSet;
}
But it only returns one permutation.
SOLUTION:
Okay i got it. This method is in class that extends ArrayList so i simply implemented Set<T> to this class and changed return type of this method to XList<Set<T>> and it worked.
You cannot do that, because a set is actually an unordered list (Collection). Moreover, creating a permutation requires an order. As a result, even if we assume that this is possible, you will end up with the same set each time, so you would have n equivalent sets.
This question already has answers here:
How to clone ArrayList and also clone its contents?
(21 answers)
Closed 2 years ago.
I've been using ArrayLists on a project of mine, and I need to create a default ArrayList so I can reset the original one whenever I want. So, I copy the original ArrayList to create the default one. However, whenever I modify something on the original, it also changes the default one. How can I make the copy "static" and unchangeable?
Here is my code: (It's in portuguese)
private ArrayList<Compartimento> listaCompartimentos;
private ArrayList<Compartimento> listaCompartimentosDEFAULT;
public Simulador() {
this.listaCompartimentos = new ArrayList<>();
this.listaCompartimentosDEFAULT=new ArrayList<>();
}
//Copy of the array
public void gravarListaDefault(){
this.listaCompartimentosDEFAULT=(ArrayList<Compartimento>)listaCompartimentos.clone();
}
Note: I don't know if it can be the reason behind it, but the ArrayList listaCompartimentos has a listaEquipamentos. For each "Compartimento" there is an ArrayList "listaEquipamentos".
clone() for ArrayLists should be avoided because even if it creates a new List instance, it holds references to the same elements. So an element changed on the first List will also be changed on the second one. Two different objects holding the same references.
The code below will create a new instance with new elements.
ArrayList<Object> realClone = new ArrayList<Object>();
for(Object o : originalList)
realClone.add(o.clone());
this.listaCompartimentosDEFAULT = new ArrayList<Compartimento>(
listaCompartimentos);
I would suggest to clone each object . Make your Compartimentoclass implements Cloneable. And clone each object in the List and add to the other List.
for(Compartimento c : this.listaCompartimentos) {
this.listaCompartimentosDEFAULT.add(c.clone());
}
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
List versus ArrayList
Difference between
ArrayList al = new ArrayList()
and
List al = new ArrayList() ?
None, from a creation perspective. Both create an instance of ArrayList.
The difference is that, in you second example, al allows access to all methods implemented on the List interface while, in the first example, al allows access to all (accessible) methods and fields of the ArrayList class.
A practical rule of thumb: use the second pattern. If you need some extra goodies from the ArrayList implementation, then you can always cast:
List list = new ArrayList();
// do some adds/removes/... on the list
((ArrayList) list).trimToSize();
Its called programming to interface. Suppose, you need to return this list from your method. So the calling code can have that into a List variable.
public ArrayList getList() {
ArrayList list = new ArrayList();
// do something with the list here
return list;
}
And this,
public List getList() {
List list = new ArrayList();
// do something with the list here
return list;
}
Now for the latter method calling code can have the returned list in List type variable. And you can easily decide later, for some reason, something like this,
public List getList() {
List list = new LinkedList();
// do something with the list here
return list;
}
No change in calling code, whereas with the former you need to change the return type, that would eventually screw up the calling code as well.
Paraphrasing my answer to this very similar question about Map vs. HashMap:
There is no difference between the objects. There is a difference in the interface you have to the object. In the first case, the interface is ArrayList, whereas in the second it's List. The underlying object, though, is the same.
The advantage to using List is that you can change the underlying object to be a different kind of list without breaking your contract with any code that's using it. If you declare it as ArrayList, you have to change your contract if you want to change the underlying implementation.