2012-06-24 14 views
22

Dire che ho una lista come:Come aggiungere un elemento in List durante l'iterazione in java?

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

Mentre scorrendo questa lista voglio aggiungere un elemento alla fine della lista. Ma non voglio scorrere i nuovi elementi aggiunti che voglio ripetere fino alla dimensione iniziale della lista.

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

Qualcuno può suggerirmi come posso farlo?

risposta

32

Non è possibile utilizzare un'istruzione foreach per questo. Il foreach utilizza internamente un iteratore:

Gli iteratori restituiti da iteratore di questa classe e listIterator metodi sono fail-fast: se la lista è strutturalmente modificato in qualsiasi momento dopo la creazione del iteratore, in alcun modo, tranne tramite i metodi di rimozione o aggiunta dello stesso iteratore , l'iteratore genererà un valore di ConcurrentModificationException pari a .

(da javadoc ArrayList)

Nella dichiarazione foreach non si ha accesso al metodo Add della iteratore e in ogni caso, che non è ancora il tipo di add che si desidera, perché non aggiunge al fine. Avrai bisogno di attraversare la lista manualmente:

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

noti che questo è efficace solo per le liste che consentono l'accesso casuale. È possibile verificare questa funzionalità controllando se l'elenco implementa l'interfaccia del marcatore RandomAccess. Un ArrayList ha accesso casuale. Una lista collegata no.

1

Si potrebbe iterare su una copia (clone) alla vostra lista originale:

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

Si noti che non è nemmeno possibile aggiungere un nuovo elemento a un elenco, mentre l'iterazione su di esso, perché si tradurrà in a ConcurrentModificationException.

8

Proprio iterare alla vecchia moda, perché è necessario esplicita manipolazione dell'indice:

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, non lo farà.Sarà quando si usa un iteratore e si aggiungono le definizioni mentre si itera, ma non quando si fa iterazione da solo qui. Gli OP –

+0

vogliono "iterare fino alla dimensione iniziale". –

+0

Doh! Povera lettura da parte mia. –

0

Faccio questo con l'aggiunta di elementi a un nuovo elenco tmp vuoto , quindi aggiungendo la lista tmp all'elenco originale usando addAll(). Ciò impedisce di copiare inutilmente un ampio elenco di fonti.

Immaginate cosa succede quando l'elenco originale dell'OP contiene alcuni milioni di elementi; per un po 'ridurrai il doppio della memoria.

Oltre a risparmiare risorse, questa tecnica ci impedisce anche di ricorrere allo stile degli anni 80 per i loop e utilizzare quelli che sono effettivamente indici di array che in alcuni casi potrebbero non essere interessanti.

Problemi correlati