valor una remover remove obtener objetos nodo metodo lista eliminar elemento como java exception list arraylist

java - remover - ¿Por qué obtengo una excepción de operación no admitida cuando intento eliminar un elemento de una lista?



remove() java (12)

A continuación se muestra un fragmento de código de 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;

entonces, lo que sucede es que cuando se llama al método asList, devuelve la lista de su propia versión de clase estática privada que no anula la función de agregar de AbstractList para almacenar el elemento en la matriz. Entonces, por defecto, el método de agregar en la lista abstracta produce una excepción.

Así que no es una lista de matrices regular.

Tengo este codigo

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, ", "); }

Entiendo esto:

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)

¿Cómo sería esta la manera correcta? Java.15


Arrays.asList () devuelve una lista que no permite operaciones que afectan su tamaño (tenga en cuenta que esto no es lo mismo que "no modificable").

Podría hacer una new ArrayList<String>(Arrays.asList(split)); para crear una copia real, pero viendo lo que estás tratando de hacer, aquí hay una sugerencia adicional (tienes un algoritmo O(n^2) justo debajo de eso).

Desea eliminar list.size() - count (llamemos k ) elementos aleatorios de la lista. Simplemente elija tantos elementos aleatorios y cámbielos a las posiciones k finales de la lista, luego elimine todo el rango (por ejemplo, usando subList () y clear () en eso). Eso lo convertiría en un algoritmo magro y medio O(n) ( O(k) es más preciso).

Actualización : como se indica a continuación, este algoritmo solo tiene sentido si los elementos no están ordenados, por ejemplo, si la Lista representa una Bolsa. Si, por otro lado, la Lista tiene un orden significativo, este algoritmo no lo mantendría (el algoritmo de los poligénelubricantes lo haría).

Actualización 2 : En retrospectiva, un algoritmo mejor (lineal, de mantenimiento, pero con números aleatorios O (n)) sería algo como esto:

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--; } }


Bastantes problemas con tu código:

En Arrays.asList devolviendo una lista de tamaño fijo

Desde la API:

Arrays.asList : devuelve una lista de tamaño fijo respaldada por la matriz especificada.

No puedes add a eso; no se puede remove de ella No puedes modificar estructuralmente la List .

Fijar

Crea una LinkedList , que permite remove más rápidamente.

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

En split tomando expresiones regulares

Desde la API:

String.split(String regex) : divide esta cadena alrededor de coincidencias de la expresión regular dada.

| es un metacarácter regex; Si quieres dividir en un literal | , debes escapar a /| , que como un literal de cadena de Java es "//|" .

Fijar:

template.split("//|")

En mejor algoritmo

En lugar de llamar a remove uno a la vez con índices aleatorios, es mejor generar suficientes números aleatorios en el rango, y luego atravesar la List una vez con un listIterator() , llamando a remove() a los índices apropiados. Hay preguntas sobre sobre cómo generar números aleatorios pero distintos en un rango determinado.

Con esto, su algoritmo sería O(N) .


Creo que reemplazando:

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

con

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

resuelve el problema


Esta UnsupportedOperationException se produce cuando intenta realizar alguna operación en la colección donde no está permitido y, en su caso, cuando llama a Arrays.asList no devuelve una java.util.ArrayList . Devuelve un java.util.Arrays$ArrayList que es una lista inmutable. No se puede agregar a ella y no se puede quitar de ella.


Este me ha quemado muchas veces. Arrays.asList crea una lista no modificable. Desde el Javadoc: devuelve una lista de tamaño fijo respaldada por la matriz especificada.

Crea una nueva lista con el mismo contenido:

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

Esto creará un poco de basura adicional, pero podrás mutarla.


La lista devuelta por Arrays.asList() puede ser inmutable. Podrías intentar

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


No puede eliminar, ni puede agregar a una lista de arrays de tamaño fijo.

Pero puedes crear tu lista secundaria de esa lista.

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, ", "); }

* Otra forma es

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

esto creará ArrayList que no es de tamaño fijo como Arrays.asList


Probablemente porque estás trabajando con un envoltorio inmodificable .

Cambia esta línea:

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

a esta linea:

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


Sí, en Arrays.asList , devolviendo una lista de tamaño fijo.

Aparte de usar una lista enlazada, simplemente use la lista de métodos addAll .

Ejemplo:

String idList = "123,222,333,444"; List<String> parentRecepeIdList = new ArrayList<String>(); parentRecepeIdList.addAll(Arrays.asList(idList.split(","))); parentRecepeIdList.add("555");


Solo lea el JavaDoc para el método asList:

Devuelve un {@code List} de los objetos en la matriz especificada. El tamaño de la {@code List} no se puede modificar, es decir, la adición y eliminación no son compatibles, pero los elementos se pueden configurar. Establecer un elemento modifica la matriz subyacente.

Esto es de Java 6 pero parece que es el mismo para el java de Android.

EDITAR

El tipo de la lista resultante es Arrays.ArrayList , que es una clase privada dentro de Arrays.class. En términos prácticos, no es más que una vista de lista en la matriz que ha pasado con Arrays.asList . Con una consecuencia: si cambia la matriz, la lista también se modifica. Y debido a que una matriz no se puede cambiar de tamaño, la operación de eliminación y adición no debe ser compatible.


Tengo otra solución para ese problema:

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

trabajar en newList ;)