299 votes

Java List.add() UnsupportedOperationException (exception)

J'essaie d'ajouter des objets à un List<String> mais il jette une UnsupportedOperationException . Quelqu'un sait-il pourquoi ?

Mon code Java :

String[] membersArray = request.getParameterValues('members');
List<String> membersList = Arrays.asList(membersArray);

for (String member : membersList) {
    Person person = Dao.findByName(member);
    List<String> seeAlso;
    seeAlso = person.getSeeAlso();
    if (!seeAlso.contains(groupDn)){
        seeAlso.add(groupDn);
        person.setSeeAlso(seeAlso);
    }
}

Le message d'erreur :

java.lang.UnsupportedOperationException
    java.util.AbstractList.add(Unknown Source)
    java.util.AbstractList.add(Unknown Source)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

568voto

Joachim Sauer Points 133411

Pas tous les List prend en charge le add() méthode.

Un exemple courant est le List retourné par Arrays.asList() : il est documenté no pour soutenir toute modification structurelle (c'est-à-dire la suppression ou l'ajout d'éléments) (c'est moi qui souligne) :

Retourne un taille fixe liste soutenue par le tableau spécifié.

Même si ce n'est pas le cas List que vous essayez de modifier, la réponse s'applique toujours à d'autres List qui sont soit immuables, soit ne permettent que certaines modifications.

Vous pouvez vous renseigner à ce sujet en lisant la documentation de l'application UnsupportedOperationException y List.add() qui indique qu'il s'agit d'une "(opération facultative)". La signification précise de cette phrase est expliquée en haut de la page d'accueil. List documentation.

Comme solution de contournement, vous pouvez créer une copie de la liste vers une implémentation connue et modifiable, telle que ArrayList :

seeAlso = new ArrayList<>(seeAlso);

1 votes

Donc je dois utiliser l'instance de la liste pour tester si elle contient mon élément et l'instance du tableau quand je dois ajouter un élément ? c'est ça écrire ?

110 votes

@Florito : Ça va marcher quand même : List<String> listMembres = new ArrayList<String>(Arrays.asList(tabMembres)); :)

0 votes

Ou peut-être que je dois convertir mon objet Liste en ArrayList ou autre ?

13voto

krmanish007 Points 1

La plupart des implémentations de listes offrent un support limité pour l'ajout et la suppression, et Arrays.asList(membersArray) en fait partie. Vous devez insérer l'enregistrement dans java.util.ArrayList ou utiliser l'approche ci-dessous pour le convertir en ArrayList.

Avec un changement minimal dans votre code, vous pouvez faire ce qui suit pour convertir une liste en ArrayList. La première solution a un changement minimal dans votre solution, mais la seconde est plus optimisée, je suppose.

    String[] membersArray = request.getParameterValues('members');
    ArrayList<String> membersList = new ArrayList<>(Arrays.asList(membersArray));

OU

    String[] membersArray = request.getParameterValues('members');
    ArrayList<String> membersList = Stream.of(membersArray).collect(Collectors.toCollection(ArrayList::new));

5voto

Yash Points 4565

Dans le concept d'héritage, si une méthode particulière n'est pas disponible dans la classe actuelle, elle sera recherchée dans les classes supérieures. Si elle est disponible, elle l'exécute.

Il exécute AbstractList<E> classe add() qui lance la méthode UnsupportedOperationException .


Lorsque vous convertissez un tableau en un objet de collection, c'est-à-dire une API basée sur un tableau en une API basée sur une collection, vous obtenez un objet de collection de taille fixe, car le comportement d'un tableau est de taille fixe.

java.util.Arrays.asList( T... a )

Soucez des échantillons pour la conformation.

public class Arrays {
    public static <T> List<T> asList(T... a) {
        return new java.util.Arrays.ArrayList.ArrayList<>(a); // Arrays Inner Class ArrayList
    }
    //...
    private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable {
        //...
    }
}
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }
    public E set(int index, E element) {
        throw new UnsupportedOperationException();
    }
    public E remove(int index) {
        throw new UnsupportedOperationException();
    }

    public Iterator<E> iterator() {
        return new Itr();
    }
    private class Itr implements Iterator<E> {
        //...
    }

    public ListIterator<E> listIterator() {
        return listIterator(0);
    }
    private class ListItr extends Itr implements ListIterator<E> {
        //...
    }
}

A partir de la source ci-dessus, vous pouvez observer que java.util.Arrays.ArrayList La classe n'est pas @Override add(index, element), set(index, element), remove(index) . Donc, de l'héritage il exécute super AbstractList<E> classe add() qui lance la fonction UnsupportedOperationException .

Como AbstractList<E> est une classe abstraite qui fournit l'implémentation de iterator() and listIterator() . Ainsi, nous pouvons itérer sur l'objet liste.

List<String> list_of_Arrays = Arrays.asList(new String[] { "a", "b" ,"c"});

try {
    list_of_Arrays.add("Yashwanth.M");
} catch(java.lang.UnsupportedOperationException e) {
    System.out.println("List Interface executes AbstractList add() fucntion which throws UnsupportedOperationException.");
}
System.out.println("Arrays → List : " + list_of_Arrays);

Iterator<String> iterator = list_of_Arrays.iterator();
while (iterator.hasNext()) System.out.println("Iteration : " + iterator.next() );

ListIterator<String> listIterator = list_of_Arrays.listIterator();
while (listIterator.hasNext())    System.out.println("Forward  iteration : " + listIterator.next() );
while(listIterator.hasPrevious()) System.out.println("Backward iteration : " + listIterator.previous());

Vous pouvez même créer des tableaux de taille fixe avec la classe Collections. Collections.unmodifiableList(list);

Source de l'échantillon :

public class Collections {
    public static <T> List<T> unmodifiableList(List<? extends T> list) {
        return (list instanceof RandomAccess ?
                new UnmodifiableRandomAccessList<>(list) :
                new UnmodifiableList<>(list));
    }
}

A Collection - parfois appelé conteneur - est simplement un objet qui regroupe plusieurs éléments en une seule unité. Les collections sont utilisées pour stocker, récupérer, manipuler et communiquer des données agrégées.

Voir aussi

3voto

Vous obtiendrez également cette exception si vous tentez de add à un List<T> retourné par Collections.singletonList(T o) :

Retourne un immuable liste contenant uniquement l'objet spécifié. La liste retournée est sérialisable.

La JVM n'implémente pas add() para Collections.singletonList

2voto

Ziv.Ti Points 222

Liste membersList = Arrays.asList(membersArray) ;

retourne une liste immuable, ce que vous devez faire c'est

new ArrayList<>(Arrays.asList(membersArray)) ; pour le rendre mutable

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X