Java lang unsupportedoperationexception ошибка

An UnsupportedOperationException is a runtime exception in Java that occurs when a requested operation is not supported. For example, if an unmodifiable List is attempted to be modified by adding or removing elements, an UnsupportedOperationException is thrown. This is one of the common exceptions that occur when working with Java collections such as List, Queue, Set and Map.

The UnsupportedOperationException is a member of the Java Collections Framework. Since it is an unchecked exception, it does not need to be declared in the throws clause of a method or constructor.

What Causes UnsupportedOperationException

An UnsupportedOperationException is thrown when a requested operation cannot be performed because it is not supported for that particular class. One of the most common causes for this exception is using the asList() method of the java.util.Arrays class. Since this method returns a fixed-size unmodifiable List, the add() or remove() methods are unsupported. Trying to add or remove elements from such a List will throw the UnsupportedOperationException exception.

Other cases where this exception can occur include:

  • Using wrappers between collections and primitive types.
  • Trying to remove elements using an Iterator.
  • Trying to add, remove or set elements using ListIterator.

UnsupportedOperationException Example

Here’s an example of an UnsupportedOperationException thrown when an object is attempted to be added to an unmodifiable List:

import java.util.Arrays;
import java.util.List;

public class UnsupportedOperationExceptionExample {
    public static void main(String[] args) {
        String array[] = {"a", "b", "c"};
        List<String> list = Arrays.asList(array);
        list.add("d");
    }
}

Since the Arrays.asList() method returns a fixed-size list, attempting to modify it either by adding or removing elements throws an UnsupportedOperationException.

Running the above code throws the exception:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.base/java.util.AbstractList.add(AbstractList.java:153)
    at java.base/java.util.AbstractList.add(AbstractList.java:111)
    at UnsupportedOperationExceptionExample.main(UnsupportedOperationExceptionExample.java:8)

How to Resolve UnsupportedOperationException

The UnsupportedOperationException can be resolved by using a mutable collection, such as ArrayList, which can be modified. An unmodifiable collection or data structure should not be attempted to be modified.

The unmodifiable List returned by the Arrays.asList() method in the earlier example can be passed to a new ArrayList object, which can be modified:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class UnsupportedOperationExceptionExample {
    public static void main(String[] args) {
        String array[] = {"a", "b", "c"};
        List<String> list = Arrays.asList(array);

        List<String> arraylist = new ArrayList<>(list);

        arraylist.add("d");

        System.out.println(arraylist);
    }
}

Here, a new ArrayList object is created using the unmodifiable list returned from the Arrays.asList() method. When a new element is added to the ArrayList, it works as expected and resolves the UnsupportedOperationException. Running the above code produces the following output:

[a, b, c, d]

Track, Analyze and Manage Errors With Rollbar

Rollbar in action

Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing Java errors easier than ever. Sign Up Today!

Привет, сегодня я хотел бы поговорить о культуре проектирования. Многие программисты (особенно джуниоры) боятся создать лишний класс, интерфейс и т.п… Причин тому, я уверен, немало, однако эта тема выходит за рамки этого поста. Но как раз из-за этого появляются очень интересные проблемы, о которых я хотел бы сегодня рассказать. Если я тебя заинтриговал — добро пожаловать под кат.

Как пример возьмем JDK интерфейс Iterator.

public interface Iterator<E> {
    
    boolean hasNext();

    E next();

    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }

} 

Этот код взят именно из JDK 1.8 не просто так. Дело в том, что в JavaDoc’е к методу remove сказано, что он может кидать UnsupportedOperationException, в случае, если реализация интерфейса его не поддерживает. И на мой взгляд это большая проблема. Конечно, я понимаю, что в JDK она вызвана поддержкой обратной совместимости и уже ничего с этим не сделаешь, ничего не сломав.

Я долго думал, как проиллюстрировать эту проблему. И вот, я обратил свое внимание на нее, когда я приехал в гости к другу. Пока друг удалился в кухню за

пивом

соком, я решил включить кондиционер, он был такой же, как и у меня дома и я без вопросов взял пульт и начал клацать. Не работает. Переподключил конциционер к сети, проверил батарейки в пульте, подошел вплотную — и нечего, мой любимый турбо-режим не работает и все, о чем я и пожаловался другу, когда он вернулся. Но тут-то меня и ждал сюрприз: «А в этой модели нет никаких турбо-режимов», — хладнокровно ответил мне друг. «Как так, вот же кнопка „turbo“», — показываю я другу пульт.

Приблизительно такие же чувства я испытываю когда мне прилетает вот такой вот UnsupportedOperationException. На мой взгляд, эта проблема должна решаться простой иерархией интерфейсов, и если с пультами проблема вызвана нерентабельностью, но ведь у нас таких проблем нет ;)

Спасибо за внимание.
Буду рад коментариям и объективной критике.

I have this code:

public static String SelectRandomFromTemplate(String template,int count) {
   String[] split = template.split("|");
   List<String> list=Arrays.asList(split);
   Random r = new Random();
   while( list.size() > count ) {
      list.remove(r.nextInt(list.size()));
   }
   return StringUtils.join(list, ", ");
}

I get this:

06-03 15:05:29.614: ERROR/AndroidRuntime(7737): java.lang.UnsupportedOperationException
06-03 15:05:29.614: ERROR/AndroidRuntime(7737):     at java.util.AbstractList.remove(AbstractList.java:645)

How would be this the correct way? Java.15

Pang's user avatar

Pang

9,481146 gold badges81 silver badges122 bronze badges

asked Jun 3, 2010 at 12:08

Pentium10's user avatar

Pentium10Pentium10

204k122 gold badges422 silver badges500 bronze badges

2

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).

answered Jun 3, 2010 at 12:19

polygenelubricants's user avatar

11

This one has burned me many times. Arrays.asList creates an unmodifiable list.
From the Javadoc: Returns a fixed-size list backed by the specified array.

Create a new list with the same content:

newList.addAll(Arrays.asList(newArray));

This will create a little extra garbage, but you will be able to mutate it.

damd's user avatar

damd

5,9596 gold badges46 silver badges76 bronze badges

answered Jun 3, 2010 at 12:11

Nick Orton's user avatar

4

Probably because you’re working with unmodifiable wrapper.

Change this line:

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

to this line:

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

Andrii Abramov's user avatar

answered Jun 3, 2010 at 12:11

Roman's user avatar

RomanRoman

64k92 gold badges237 silver badges329 bronze badges

5

The list returned by Arrays.asList() might be immutable. Could you try

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

answered Jun 3, 2010 at 12:11

Pierre's user avatar

PierrePierre

34.3k31 gold badges111 silver badges191 bronze badges

2

I think that replacing:

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

with

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

resolves the problem.

Jameson's user avatar

Jameson

6,3416 gold badges31 silver badges52 bronze badges

answered Sep 8, 2013 at 20:35

Salim Hamidi's user avatar

Salim HamidiSalim Hamidi

20.6k1 gold badge25 silver badges31 bronze badges

The issue is you’re creating a List using Arrays.asList() method with fixed Length
meaning that

Since the returned List is a fixed-size List, we can’t add/remove elements.

See the below block of code that I am using

This iteration will give an Exception Since it is an iteration list Created by asList() so remove and add are not possible, it is a fixed array

List<String> words = Arrays.asList("pen", "pencil", "sky", "blue", "sky", "dog"); 
for (String word : words) {
    if ("sky".equals(word)) {
        words.remove(word);
    }
}   

This will work fine since we are taking a new ArrayList we can perform modifications while iterating

List<String> words1 = new ArrayList<String>(Arrays.asList("pen", "pencil", "sky", "blue", "sky", "dog"));
for (String word : words) {
    if ("sky".equals(word)) {
        words.remove(word);
    }
}

elarcoiris's user avatar

elarcoiris

1,8744 gold badges28 silver badges30 bronze badges

answered Oct 4, 2020 at 9:26

Sachin Gowda's user avatar

1

Just read the JavaDoc for the asList method:

Returns a {@code List} of the objects
in the specified array. The size of
the {@code List} cannot be modified,
i.e. adding and removing are
unsupported, but the elements can be
set. Setting an element modifies the
underlying array.

This is from Java 6 but it looks like it is the same for the android java.

EDIT

The type of the resulting list is Arrays.ArrayList, which is a private class inside Arrays.class. Practically speaking, it is nothing but a List-view on the array that you’ve passed with Arrays.asList. With a consequence: if you change the array, the list is changed too. And because an array is not resizeable, remove and add operation must be unsupported.

answered Jun 3, 2010 at 12:14

Andreas Dolk's user avatar

Andreas DolkAndreas Dolk

113k18 gold badges179 silver badges267 bronze badges

Arrays.asList() returns a list that doesn’t allow operations affecting its size (note that this is not the same as «unmodifiable»).

You could do new ArrayList<String>(Arrays.asList(split)); to create a real copy, but seeing what you are trying to do, here is an additional suggestion (you have a O(n^2) algorithm right below that).

You want to remove list.size() - count (lets call this k) random elements from the list. Just pick as many random elements and swap them to the end k positions of the list, then delete that whole range (e.g. using subList() and clear() on that). That would turn it to a lean and mean O(n) algorithm (O(k) is more precise).

Update: As noted below, this algorithm only makes sense if the elements are unordered, e.g. if the List represents a Bag. If, on the other hand, the List has a meaningful order, this algorithm would not preserve it (polygenelubricants’ algorithm instead would).

Update 2: So in retrospect, a better (linear, maintaining order, but with O(n) random numbers) algorithm would be something like this:

LinkedList<String> elements = ...; //to avoid the slow ArrayList.remove()
int k = elements.size() - count; //elements to select/delete
int remaining = elements.size(); //elements remaining to be iterated
for (Iterator i = elements.iterator(); k > 0 && i.hasNext(); remaining--) {
  i.next();
  if (random.nextInt(remaining) < k) {
     //or (random.nextDouble() < (double)k/remaining)
     i.remove();
     k--;
  }
}

answered Jun 3, 2010 at 12:17

Dimitris Andreou's user avatar

Dimitris AndreouDimitris Andreou

8,8062 gold badges32 silver badges36 bronze badges

1

This UnsupportedOperationException comes when you try to perform some operation on collection where its not allowed and in your case, When you call Arrays.asList it does not return a java.util.ArrayList. It returns a java.util.Arrays$ArrayList which is an immutable list. You cannot add to it and you cannot remove from it.

answered Jun 3, 2010 at 13:30

Mayank Gupta's user avatar

I’ve got another solution for that problem:

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

work on newList ;)

Andrii Abramov's user avatar

answered Feb 17, 2015 at 1:09

ZZ 5's user avatar

ZZ 5ZZ 5

1,67425 silver badges41 bronze badges

Replace

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

to

List<String> list = New ArrayList<>();
list.addAll(Arrays.asList(split));

or

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

or

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

or (Better for Remove elements)

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

answered Nov 16, 2018 at 13:56

Karthik Kompelli's user avatar

Karthik KompelliKarthik Kompelli

2,0861 gold badge18 silver badges22 bronze badges

Yes, on Arrays.asList, returning a fixed-size list.

Other than using a linked list, simply use addAll method list.

Example:

String idList = "123,222,333,444";

List<String> parentRecepeIdList = new ArrayList<String>();

parentRecepeIdList.addAll(Arrays.asList(idList.split(","))); 

parentRecepeIdList.add("555");

Andrii Abramov's user avatar

answered Sep 23, 2013 at 11:35

Sameer Kazi's user avatar

Sameer KaziSameer Kazi

17k2 gold badges34 silver badges46 bronze badges

You can’t remove, nor can you add to a fixed-size-list of Arrays.

But you can create your sublist from that list.

list = list.subList(0, list.size() - (list.size() - count));

public static String SelectRandomFromTemplate(String template, int count) {
   String[] split = template.split("\|");
   List<String> list = Arrays.asList(split);
   Random r = new Random();
   while( list.size() > count ) {
      list = list.subList(0, list.size() - (list.size() - count));
   }
   return StringUtils.join(list, ", ");
}

*Other way is

ArrayList<String> al = new ArrayList<String>(Arrays.asList(template));

this will create ArrayList which is not fixed size like Arrays.asList

Andrii Abramov's user avatar

answered Jul 4, 2013 at 19:22

Venkat's user avatar

VenkatVenkat

1573 bronze badges

Arrays.asList() uses fixed size array internally.
You can’t dynamically add or remove from thisArrays.asList()

Use this

Arraylist<String> narraylist=new ArrayList(Arrays.asList());

In narraylist you can easily add or remove items.

Nordle's user avatar

Nordle

2,8953 gold badges15 silver badges34 bronze badges

answered May 24, 2019 at 10:23

Roushan Kumar's user avatar

Arraylist narraylist=Arrays.asList(); // Returns immutable arraylist
To make it mutable solution would be:
Arraylist narraylist=new ArrayList(Arrays.asList());

answered Jun 21, 2019 at 15:15

BruceWayne's user avatar

1

Following is snippet of code from Arrays

public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

    /**
     * @serial include
     */
    private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {
        private static final long serialVersionUID = -2764017481108945198L;
        private final E[] a;

so what happens is that when asList method is called then it returns list of its own private static class version which does not override add funcion from AbstractList to store element in array. So by default add method in abstract list throws exception.

So it is not regular array list.

answered Apr 15, 2016 at 4:10

Gagandeep Singh's user avatar

Gagandeep SinghGagandeep Singh

17.2k1 gold badge16 silver badges18 bronze badges

Creating a new list and populating valid values in new list worked for me.

Code throwing error —

List<String> list = new ArrayList<>();
   for (String s: list) {
     if(s is null or blank) {
        list.remove(s);
     }
   }
desiredObject.setValue(list);

After fix —

 List<String> list = new ArrayList<>();
 List<String> newList= new ArrayList<>();
 for (String s: list) {
   if(s is null or blank) {
      continue;
   }
   newList.add(s);
 }
 desiredObject.setValue(newList);

answered Sep 27, 2019 at 10:29

Bhagyashree Nigade's user avatar

Почему когда я вызываю метод listArr.remove() , у меня кидает исключение ( List listArr = Arrays.asList(array) )

Почему когда я вызываю метод listArr.remove() , у меня кидает исключение

Exception in thread "main" java.lang.UnsupportedOperationException at java.util.AbstractList.remove(AbstractList.java:161)
 List<String> listArr = Arrays.asList(array)
где String[] array это проинициализированный корректный массив

package com.javarush.task.task22.task2207;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.util.*;

/*
Обращенные слова
*/

public class Solution {
public static List<Pair> result = new ArrayList<>();

public static void main(String[] args) {
ArrayList<Pair> result = new ArrayList<>();
Scanner sc = new Scanner(System.in);
StringBuilder sb = new StringBuilder();
try(BufferedReader br = new BufferedReader(new FileReader(sc.nextLine()))){//»C:\Java\f1.txt»
while (br.ready()){
sb.append(» «).append(br.readLine());
}
}catch (Exception e){}

String strArr = sb.toString();
String[] array = strArr.trim().split(» +»);
// List<String> listArr = Arrays.asList(array);
ArrayList<String > listArr = new ArrayList<>();
Collections.addAll(listArr,array);

for (int i = 0; i < listArr.size(); i++) {
for (int j = 0; j < listArr.size();) {
if(i>=listArr.size()) break;
String revers = new StringBuilder(listArr.get(i)).reverse().toString();
if(revers.equals(listArr.get(j))&&i!=j){
Pair p = new Pair();
p.first=listArr.get(i);p.second=listArr.get(j);
result.add(p);
listArr.remove(j);
listArr.remove(i);
j=0;
}else j++;
}
}
for (Pair p:result) System.out.println(p.first+» «+p.second);
}

public static class Pair {
String first;
String second;

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

Pair pair = (Pair) o;

if (first != null ? !first.equals(pair.first) : pair.first != null) return false;
return second != null ? second.equals(pair.second) : pair.second == null;

}

@Override
public int hashCode() {
int result = first != null ? first.hashCode() : 0;
result = 31 * result + (second != null ? second.hashCode() : 0);
return result;
}

@Override
public String toString() {
return first == null && second == null ? «» :
first == null ? second :
second == null ? first :
first.compareTo(second) < 0 ? first + » » + second : second + » » + first;

}
}

}

Этот веб-сайт использует данные cookie, чтобы настроить персонально под вас работу сервиса. Используя веб-сайт, вы даете согласие на применение данных cookie. Больше подробностей — в нашем Пользовательском соглашении.

Improve Article

Save Article

Like Article

  • Read
  • Discuss
  • Improve Article

    Save Article

    Like Article

    The UnsupportedOperationException is one of the common exceptions that occur when we are working with some API of list implementation. It is thrown to indicate that the requested operation is not supported.

    This class is a member of the Java Collections Framework.

    All java errors implement the java.lang.Throwable interface or are inherited from another class. The hierarchy of this Exception is-

      java.lang.Object

             java.lang.Throwable

                       java.lang.Exception

                              java.lang.RuntimeException

                                      java.lang.UnsupportedOperationException

    Syntax:

    public class UnsupportedOperationException
    extends RuntimeException

    The main reason behind the occurrence of this error is the asList method of java.util.Arrays class returns an object of an ArrayList which is nested inside the class java.util.Arrays. ArrayList extends java.util.AbstractList and it does not implement add or remove method. Thus when this method is called on the list object, it calls to add or remove method of AbstractList class which throws this exception. Moreover, the list returned by the asList method is a fixed-size list therefore it cannot be modified.

    The below example will result in UnsupportedOperationException as it is trying to add a new element to a fixed-size list object

    Java

    import java.util.Arrays;

    import java.util.List;

    public class Example {

        public static void main(String[] args)

        {

            String str[] = { "Apple", "Banana" };

            List<String> l = Arrays.asList(str);

            System.out.println(l);

            l.add("Mango");

        }

    }

    Output:

    Exception in thread "main" java.lang.UnsupportedOperationException
        at java.base/java.util.AbstractList.add(AbstractList.java:153)
        at java.base/java.util.AbstractList.add(AbstractList.java:111)
        at Example.main(Example.java:14)

    We can solve this problem by using a mutable List that can be modified such as an ArrayList. We create a List using Arrays.asList method as we were using earlier and pass that resultant List to create a new ArrayList object. 

    Java

    import java.util.ArrayList;

    import java.util.List;

    import java.util.*;

    public class Example {

        public static void main(String[] args) {

            String str[] = { "Apple", "Banana" };

            List<String> list = Arrays.asList(str); 

            List<String> l = new ArrayList<>(list);

            l.add("Mango");

            for(String s: l )

              System.out.println(s);

        }

    }

    Last Updated :
    09 Mar, 2021

    Like Article

    Save Article

    Понравилась статья? Поделить с друзьями:
  • Java install ошибка 1603
  • Java init ошибка
  • Java import ошибка
  • Java illegal escape character ошибка
  • Java heap space ошибка как исправить edeclaration