web-dev-qa-db-fra.com

Java List.add () UnsupportedOperationException

J'essaie d'ajouter des objets à une instance List<String>, mais elle 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 (Source inconnue) 
 Java.util.AbstractList.add (Source inconnue) 
 javax.servlet.http.HttpServlet.service (HttpServlet.Java:641) 
 javax.servlet.http.HttpServlet.service (HttpServlet.Java:722) 
157
FAjir

Toutes les List implementation ne prennent pas en charge la méthode add().

Un exemple courant est la List renvoyée par Arrays.asList() : elle est documentée pas pour prendre en charge toute modification structurelle (c'est-à-dire supprimer ou ajouter des éléments) (c'est moi qui souligne):

Retourne une liste fixed-size sauvegardée par le tableau spécifié.

Même si ce n'est pas la variable List que vous essayez de modifier, la réponse s'applique aux autres implémentations List immuables ou n'autorisant que certaines modifications sélectionnées.

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

Pour contourner ce problème, vous pouvez créer une copie de la liste dans une implémentation modifiable connue, telle que ArrayList:

seeAlso = new ArrayList<>(seeAlso);
340
Joachim Sauer

Vous devez initialiser votre liste voir aussi: 

List<String> seeAlso = new Vector<String>();

ou 

List<String> seeAlso = new ArrayList<String>();
4
dwayne

Formez le concept d'héritage. Si une méthode spécifique n'est pas disponible dans la classe actuelle, elle la recherchera dans les super classes. Si disponible, il s'exécute.

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


Lorsque vous convertissez un tableau en une collection Obejct. c'est-à-dire une API basée sur un tableau à une collection, elle va ensuite vous fournir un objet de collection de taille fixe, car le comportement de Array est de taille fixe.

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

Échantillons de souce 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> {
        //...
    }
}

Formez la source ci-dessus, vous remarquerez que la classe Java.util.Arrays.ArrayList ne possède pas @Override add(index, element), set(index, element), remove(index). Ainsi, à partir de l'héritage, il exécute la super AbstractList<E> classe add() qui lève UnsupportedOperationException.

Comme AbstractList<E> est une classe abstraite, il fournit l'implémentation de iterator() and listIterator(). Nous pouvons donc parcourir 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 un tableau sous forme de tableau de taille fixe Collections class 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));
    }
}

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

@voir également

1
Yash

De nombreuses implémentations de la liste prennent en charge une assistance limitée à ajouter/supprimer, et Arrays.asList (membersArray) en fait partie. Vous devez insérer l'enregistrement dans Java.util.ArrayList ou utiliser l'approche ci-dessous pour convertir en ArrayList.

Avec le minimum de changements dans votre code, vous pouvez faire ci-dessous pour convertir une liste en ArrayList. La première solution consiste à modifier le moins possible votre solution, mais la seconde est plus optimisée, je suppose.

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

OR

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

List membersList = Arrays.asList (membersArray); 

renvoie la liste immuable, ce que vous devez faire est 

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

0
Ziv.Ti

au lieu d'utiliser add (), nous pouvons utiliser addall ()

{ seeAlso.addall(groupDn); }

add ajoute un seul élément, tandis que addAll ajoute chaque élément de la collection un par un. En fin de compte, les deux méthodes renvoient true si la collection a été modifiée. Dans le cas de ArrayList, ceci est trivial, car la collection est toujours modifiée, mais d'autres collections, telles que Set, peuvent renvoyer false si des éléments ajoutés sont déjà présents.

0
Allen