2012-06-24 11 views
22

Decir que tengo una lista como:¿Cómo agregar elementos en la Lista mientras se itera en Java?

List<String> list = new ArrayList<>(); 
list.add("a"); 
list.add("h"); 
list.add("f"); 
list.add("s"); 

Mientras iteración a través de esta lista, quiero añadir un elemento al final de la lista. Pero no quiero iterar a través de los elementos recién agregados, es decir, quiero iterar hasta el tamaño inicial de la lista.

for (String s : list) 
    /* Here I want to add new element if needed while iterating */ 

¿Alguien me puede decir cómo puedo hacer esto?

Respuesta

32

No puede usar una instrucción foreach para eso. El foreach está utilizando internamente un iterador:

Los iteradores devueltos por el iterador de esta clase y listIterator métodos son a prueba de rápida: si la lista se modifica estructuralmente en cualquier tiempo después de crear el iterador, en modo alguno, excepto a través de los métodos de eliminar o agregar del iterador , el iterador arrojará una ConcurrentModificationException.

(De javadoc ArrayList)

En la instrucción foreach usted no tiene acceso al método add del repetidor y en todo caso que todavía no es el tipo de complemento que desea porque no anexa al el fin. Tendrá que recorrer la lista manualmente:

int listSize = list.size(); 
for(int i = 0; i < listSize; ++i) 
    list.add("whatever"); 

Tenga en cuenta que esto sólo es eficiente para listas que permiten el acceso aleatorio. Puede verificar esta función comprobando si la lista implementa la interfaz del marcador RandomAccess. Un ArrayList tiene acceso aleatorio. Una lista vinculada no lo hace.

1

Se podría iterar en una copia (clon) de su lista original:

List<String> copy = new ArrayList<String>(list); 
for (String s : copy) { 
    // And if you have to add an element to the list, add it to the original one: 
    list.add("some element"); 
} 

Tenga en cuenta que ni siquiera es posible añadir un nuevo elemento a la lista, mientras que la iteración en él, ya que dará lugar a a ConcurrentModificationException.

8

Sólo iterar la manera pasada de moda, ya que es necesario un manejo índice explícito:

List myList = ... 
... 
int length = myList.size(); 
for(int i = 0; i < length; i++) { 
    String s = myList.get(i); 
    // add items here, if you want to 
} 
+1

No, no lo hará.Lo hará cuando utilice un iterador y agregue argumentos mientras itera, pero no cuando haga iteraciones por su cuenta aquí. –

+0

OP quiere "iterar hasta el tamaño inicial". –

+0

Doh! Pobre lectura de mi parte. –

0

hago esto mediante la adición de los elementos de una nueva lista de tmp, vacío , luego agregue la lista de tmp a la lista original usando addAll(). Esto evita la copia innecesaria de una gran lista de fuentes.

Imagine lo que sucede cuando la lista original del OP tiene algunos millones de elementos; por un tiempo chuparás el doble de memoria.

Además de conservar recursos, esta técnica también evita que tengamos que recurrir a bucles estilo 80 para usar lo que son índices de matriz efectivamente que en algunos casos podrían ser poco atractivos.

Cuestiones relacionadas