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 forma correcta? Java.15
Respuestas:
Algunos problemas con su código:
Al
Arrays.asList
devolver una lista de tamaño fijoDe la API:
No puedes
add
hacerlo; no puedesremove
de eso. No se puede modificar estructuralmente elList
.Reparar
Cree un
LinkedList
, que admite más rápidoremove
.Al
split
tomar expresiones regularesDe la API:
|
es un metacarácter regex; si desea dividir en un literal|
, debe escapar a él\|
, que es un literal de cadena Java"\\|"
.Reparar:
En mejor algoritmo
En lugar de llamar
remove
uno a la vez con índices aleatorios, es mejor generar suficientes números aleatorios en el rango, y luego atravesarList
una vez con unlistIterator()
, llamandoremove()
a los índices apropiados. Hay preguntas sobre stackoverflow sobre cómo generar números aleatorios pero distintos en un rango dado.Con esto, su algoritmo sería
O(N)
.fuente
Random
cada vez. Hazlo unstatic
campo y siembra solo una vez.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:
Esto creará un poco de basura extra, pero podrás mutarlo.
fuente
Probablemente porque estás trabajando con un contenedor no modificable .
Cambia esta línea:
a esta línea:
fuente
unmodifiable
yimmutable
.unmodifiable
significa exactamente "modificable, pero no estructuralmente".unmodifiableList
contenedor y probar unset
; lanzaUnsupportedOperationException
. Estoy bastante seguro de queCollections.unmodifiable*
realmente significa inmutabilidad total, no solo estructural.Creo que reemplazando:
con
resuelve el problema
fuente
La lista devuelta por
Arrays.asList()
podría ser inmutable. Podrías intentarfuente
Simplemente lea el JavaDoc para el método asList:
Esto es de Java 6 pero parece que es lo mismo para el Android Java.
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 con la que ha pasadoArrays.asList
. Con una consecuencia: si cambia la matriz, la lista también cambia. Y debido a que una matriz no es redimensionable, la operación de eliminar y agregar no debe ser compatible.fuente
Arrays.asList () devuelve una lista que no permite operaciones que afecten su tamaño (tenga en cuenta que esto no es lo mismo que "no modificable").
Podría hacer
new ArrayList<String>(Arrays.asList(split));
para crear una copia real, pero viendo lo que está tratando de hacer, aquí hay una sugerencia adicional (tiene unO(n^2)
algoritmo justo debajo de eso).Desea eliminar
list.size() - count
(llamemos a estok
) elementos aleatorios de la lista. Simplemente elija tantos elementos aleatorios y cámbielos a lask
posiciones finales de la lista, luego elimine todo ese rango (por ejemplo, usando subList () y clear () en eso). Eso lo convertiría en unO(n)
algoritmo magro y medio (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 preservaría (el algoritmo de los poligeneles lubricantes lo haría).
Actualización 2 : Entonces, en retrospectiva, un algoritmo mejor (lineal, manteniendo el orden, pero con números aleatorios O (n)) sería algo como esto:
fuente
ArrayList
. Mucho más simple que mi sugerencia. Sin embargo, creo que resultaría en un reordenamiento de los elementos.Tengo otra solución para ese problema:
trabajar en
newList
;)fuente
Esta excepción de operación no admitida se produce cuando intenta realizar alguna operación en la recopilación donde no está permitido y, en su caso, cuando llama
Arrays.asList
no devuelve ajava.util.ArrayList
. Devuelve unjava.util.Arrays$ArrayList
que es una lista inmutable. No puede agregarle ni eliminarlo.fuente
Sí, en
Arrays.asList
, devolviendo una lista de tamaño fijo.Aparte de usar una lista vinculada, simplemente use la
addAll
lista de métodos.Ejemplo:
fuente
Reemplazar
a
o
o
o (Mejor para eliminar elementos)
fuente
Arraylist narraylist = Arrays.asList (); // Devuelve una lista de matrices inmutable Para que sea una solución mutable sería: Arraylist narraylist = new ArrayList (Arrays.asList ());
fuente
A continuación se muestra un fragmento de código de matrices
Entonces, lo que sucede es que cuando se llama al método asList, devuelve una lista de su propia versión de clase estática privada que no anula la función agregar de AbstractList para almacenar el elemento en la matriz. Entonces, por defecto, el método add en la lista abstracta arroja una excepción.
Por lo tanto, no es una lista de matriz regular.
fuente
No puede eliminar ni agregar a una lista de matrices de tamaño fijo.
Pero puedes crear tu sublista desde esa lista.
list = list.subList(0, list.size() - (list.size() - count));
* Otra forma es
esto creará ArrayList que no tiene un tamaño fijo como Arrays.asList
fuente
Arrays.asList()
utiliza una matriz de tamaño fijo internamente.No puede agregar o quitar dinámicamente de esto
Arrays.asList()
Utilizar este
En
narraylist
puedes agregar o quitar elementos fácilmente.fuente
Crear una nueva lista y completar valores válidos en una nueva lista me funcionó.
Error de lanzamiento de código:
Después de arreglarlo
fuente