2011-06-07 8 views
36

ArrayList 's iterador de la lista no poner en práctica el método remove, sin embargo, me sale el siguiente excepción lanzada: UnsupportedOperationException en java.util.AbstractList.remove (AbstractList.java:144)UnsupportedOperationException en AbstractList.remove() al operar en ArrayList

Por este código:

protected void removeZeroLengthStringsFrom(List<String> stringList) 
{ 
    ListIterator<String> iter = stringList.listIterator(); 
    String s; 
    while (iter.hasNext()) 
    { 
     s = iter.next(); 
     if (s.length() == 0) 
     { 
      iter.remove(); 
     } 
    } 
} 

Qué me estoy perdiendo aquí? He verificado que el List<String> que estoy pasando son de hecho ArrayList<String>.

Gracias!

+0

¿Hay más de un subproceso operativo en la misma 'Lista '? –

+0

Sugiero que verifique que el tipo de tiempo de ejecución de 'stringList' es _really_ de tipo java.util.ArrayList. Sospecho que puede tener un 'Vector' o' Stack' o un 'ArrayList' de algún paquete diferente que no anule' remove (int) '. –

+0

¿Cómo lo verificaste? ¿Has examinado directamente 'stringList.getClass()' dentro de 'removeZeroLengthStringsFrom()', etc.? – QuantumMechanic

Respuesta

113

creo que pueda estar usando la utilidad Arrays para obtener el List que se pasa en ese método. El objeto es realmente del tipo ArrayList, pero es java.util.Arrays.ArrayList, no java.util.ArrayList.

La versión java.util.Arrays.ArrayList es inmutable y su método remove() no se reemplaza. Como tal, difiere a la implementación AbstractList de remove(), que arroja un UnsupportedOperationException.

+0

¿Cuál es la solución para eso? – Exceptional

+25

La solución sería algo como esto: nueva ArrayList <> (Arrays.asList ("a", "b", "c")) – Kong

+1

Existen dos posibles soluciones. El primero, como implicó Kong, es hacer una copia de la ArrayList inmutable y pasarla. La segunda, y preferible (en mi opinión), solución es volver a escribir 'eliminar ...' para devolver una lista y construir una nueva Lista mutable en el método, devolviéndola a la persona que llama. Esa solución no siempre será plausible (por ejemplo, si está enganchado en un marco que no puede modificar), pero O (n) (iterar) es ligeramente mejor que O (2n) (copiar y luego iterar). –

2

Dudo que se le haya pasado una ArrayList, ya que el método de eliminación en el iterador de ArrayList no arroja esa excepción.

Supongo que se le ha pasado una clase derivada de usuario de ArrayList cuyo iterador arroja esa excepción al eliminar.

public void remove() { 
    if (lastRet == -1) 
    throw new IllegalStateException(); 
     checkForComodification(); 

    try { 
    AbstractList.this.remove(lastRet); 
    if (lastRet < cursor) 
     cursor--; 
    lastRet = -1; 
    expectedModCount = modCount; 
    } catch (IndexOutOfBoundsException e) { 
    throw new ConcurrentModificationException(); 
    } 
} 
Cuestiones relacionadas