2008-11-18 24 views
9

Digamos que tengo un List objeto y un iterador para esa lista.Cuando ordeno una Lista, ¿qué ocurre con sus iteradores?

Ahora puedo ordenar la lista con java.util.Collections.sort()

  • ¿Qué ocurre con el repetidor?
  • ¿Aún se define su comportamiento y aún se puede usar?
  • En caso negativo, ¿puedo evitar destruir los iteradores de la lista?

Lo sé, este problema podría ser evitado cambiando el diseño del programa, clonando la lista, por ejemplo, pero específicamente quiero saber el comportamiento "oficial" de Java.

Respuesta

15

La mayor parte de las colecciones en java.util son "fail-fast" y puede lanzar una ConcurrentModificationException si se cambia la colección subyacente. Cabe señalar que esto está destinado a la depuración y, por lo tanto, no está garantizado. De acuerdo con los javadocs, esto es cierto para todos los difuntos de AbstractList, pero esto es no verdadero de CopyOnWriteArrayList, que está destinado para el uso de subprocesos múltiples.

17

Los iteradores generalmente no son válidos después de cualquier modificación de sus colecciones subyacentes, excepto a través del propio iterador. (Por ejemplo, ListIterator permite la inserción y eliminación).

Sin duda, esperaría que cualquier iterador se invalidara después de una clasificación, y si no lo fueran, no tendría ni idea de qué orden esperar.

+0

Es una respuesta clara para el iterador simple 'p' que apunta a la colección' c'. ¿Qué tal tener dos iteradores 'p' y' q' apuntando a la misma colección 'c' y repetidos de forma independiente? Does _ "excepto a través del iterador mismo" _ significa instancia específica de iterador como 'p' o significa cualquier instancia de iterador? Supongo que la iteración independiente de 'p' y' q' se invalidará entre sí (simplemente porque ninguno de los iteradores sabe de otros iteradores ni la colección recuerda todos sus iteradores), pero es bueno aclararlo aquí. ¡Gracias! – uvsmtid

+1

@uvsmtid: Es excepto a través de ese iterador específico. Si tiene dos iteradores sobre la misma colección, entonces no puede modificar la colección a través de ninguno de ellos, a menos que sea una colección que admita explícitamente la modificación simultánea. –

4

En general, cualquier tipo de mutación en una colección invalidará sus iteradores. Una mutación hecha a través de un iterador no invalidará ese iterador. Hay algunas implementaciones de colecciones excepcionales, como CopyOnWriteArrayList.

La solución general sería ordenar una copia de la colección o recrear sus iteradores.

2

Escribí un código para ver qué sucede cuando se ordena una colección mientras está iterando. Parece que el iterador no arroja ninguna excepción, pero continúa iterando normalmente. Aún le da resultados incorrectos si espera iterar sobre la colección sin clasificar. Mira eso:

public static void main(String[] args) { 
    List<String> list = new ArrayList<String>(); 
    list.add("D"); 
    list.add("B"); 
    list.add("A"); 
    list.add("C"); 
    list.add("E"); 

    Iterator<String> it = list.iterator(); 
    String s = it.next(); 
    System.out.println(s); 
    s = it.next(); 
    System.out.println(s); 

    Collections.sort(list); 
    Iterator<String> it2 = list.iterator(); 

    s = it.next(); 
    System.out.println(s); 
    s = it.next(); 
    System.out.println(s); 
    s = it.next(); 
    System.out.println(s); 

    while (it2.hasNext()) { 
     System.out.println(it2.next()); 
    } 
    } 

Espero que ayude.

+0

Donde "normalmente" incluye "podría ver el mismo elemento otra vez" ... Estoy un poco decepcionado de que esto no arroje una excepción, para ser honesto. –

+0

No se garantiza que se lanzará la excepción, es para la depuración. – sblundy

Cuestiones relacionadas