remove () en la lista creada por Arrays.asList () arroja UnsupportedOperationException

91

Tengo una colección c1<MyClass>y una matriz a<MyClass>. Estoy tratando de convertir la matriz en una colección c2y lo hago c1.removeAll(c2), pero esto arroja UnsupportedOperationException. Descubrí que la asList()clase of Arrays devuelve la Arrays.ArrayListclase y esta clase hereda la removeAll()de AbstractList()cuya implementación arroja UnsupportedOperationException.

    Myclass la[] = getMyClass();
    Collection c = Arrays.asList(la);
    c.removeAll(thisAllreadyExistingMyClass);

¿Hay alguna forma de eliminar los elementos? por favor ayuda

javalearner
fuente
Pregunta relacionada: stackoverflow.com/questions/2965747/…
Ram

Respuestas:

170

Arrays.asListdevuelve una Listenvoltura alrededor de una matriz. Este contenedor tiene un tamaño fijo y está respaldado directamente por la matriz, y como tal, las llamadas a setmodificarán la matriz, y cualquier otro método que modifique la lista arrojará un UnsupportedOperationException.

Para solucionar esto, debe crear una nueva lista modificable copiando el contenido de la lista contenedora. Esto es fácil de hacer usando el ArrayListconstructor que toma un Collection:

Collection c = new ArrayList(Arrays.asList(la));
Etienne de Martel
fuente
1
Estaba mirando el código fuente del java.util.Arrays asList()método y parece devolver un ArrayList. Sin embargo, cuando hago un System.out.println(list.getClass());, obtengo class java.util.Arrays$ArrayList. Entonces usa la ArrayListclase interna , que no tiene un método addo remove. Me pregunto cuál es el punto de tener una ArrayListclase interna en lugar de usar java.util.ArrayListuna y por qué no tener un método add()y remove().
Abdul
Corrección a mi comentario anterior: tiene un método addyremove
Abdul
1
@Abdul Porque no existe un tamaño fijo java.util.ArrayList. Desea una implementación Listque arroje una excepción si hace algo ilegal con ella (como agregar o eliminar), y ArrayListno cumple con ese requisito.
Etienne de Martel
@Abdul Arrays.asListsolo crea un contenedor List. Pero sigue siendo un java.util.List, por lo que debe tener esos métodos. Pero no se pueden aplicar porque eso llevaría a crear una nueva matriz con un tamaño diferente. Lo cual no se puede hacer porque las modificaciones que aún puede hacer se pueden realizar tanto a través de la Lista devuelta como de la matriz original. Esto no será posible si la Lista devuelta pudiera cambiar de modo que básicamente desechara la referencia de matriz original.
Adam Hošek
13

Sí, la Arrays.asList(..)colección es que no se puede expandir ni reducir (porque está respaldada por la matriz original y no se puede cambiar de tamaño).

Si desea eliminar elementos, cree new ArrayList(Arrays.asList(..)o elimine elementos directamente de la matriz (eso será menos eficiente y más difícil de escribir)

Bozho
fuente
+1 Esta respuesta es la única correcta: Arrays.asList () devuelve una lista no modificable ; eso es lo que genera la excepción. No tiene nada que ver con estar "respaldado por una matriz", etc ... todas las ArrayLists están respaldadas por matrices, gran cosa.
Bohemio
1
Pero si leyeras más en los documentos, te darías cuenta de que en realidad no es inmodificable ... "Devuelve una lista de tamaño fijo respaldada por la matriz especificada. (Los cambios en la lista devuelta" escriben "en la matriz .) "-1, Etienne tiene razón.
Steven Schlansker
1
@Steven Sí, por eso dice "tamaño fijo" en lugar de "no modificable" o "solo lectura". En realidad, editaré mi respuesta ahora mismo para reflejar eso.
Etienne de Martel
1
@Bohemian, Las colecciones devueltas son de hecho 'modificables' porque es posible llamar al método 'set'.
javalearner
2
Si va a recoger liendres así, también podría decir cosas insípidas como "arroja UnsupportedOperationException porque hay una declaración throw UnsupportedOperationException en el código". A los consumidores de una API no les importa qué superclase de AbstractBlah está lanzando una excepción, les importa cuáles son los contratos y las expectativas de la clase que usan. En JVM v + 1, es muy posible que la biblioteca de clases cambie donde se lanza la excepción, pero el contrato no cambiará.
Steven Schlansker
7

Esa es la forma en que Array.asList()funciona, porque está respaldado directamente por la matriz. Para obtener una lista completamente modificable, tendría que clonar la colección en una colección creada por usted mismo.

Collection c = new ArrayList(Arrays.asList(la))
henko
fuente
1
La lista es modificable pero solo a través de set (). la colección devuelta es de tamaño fijo.
javalearner
En realidad, nunca dije que fuera inmodificable. Solo que para obtener una lista (completamente) modificable, tendría que usar un archivo ArrayList. Sin embargo, la diferencia quizás no fue demasiado clara. :-) Si la lista es modificable o no es una cuestión de definición, es "semi-modificable" pero no completamente modificable en mi opinión.
henko