2010-10-15 10 views

risposta

17

No, l'intero punto del ciclo for-each-loop è quello di astrarre l'iteratore sottostante.

Se è necessario, è necessario dichiararlo.

+1

E quando lo si dichiara, dovrebbe essere un ListIterator se si prevede di rimuovere elementi dall'elenco. –

1

Utilizzare invece un ciclo for.

4

No, non è possibile rimuovere gli oggetti in a per ogni ciclo.

Utilizzare questo invece:

Iterator<Type> it = collection.iterator(); 

while (it.hasNext()) { 
    if (it.next().shouldBeRemoved()) { 
     it.remove(); 
    } 
} 
+3

Preferisco generalmente l'idioma 'for' piuttosto che l'idioma' while' perché mantiene più piccolo l'ambito dell'iteratore. – dty

+3

@dty: c'è un punto valido nel desiderio di mantenere il più stretto possibile l'ambito di tutte le variabili. Ma per quanto mi riguarda, la leggibilità del codice è al primo posto. La mia versione potrebbe essere letta quasi come una frase normale: 'mentre l'iteratore ha il prossimo elemento, procedi come segue: ...', e il tuo sembra molto macchinoso. Quindi, se vogliamo mantenere benefici da entrambi gli approcci, vale la pena estrarre il mio codice in un metodo separato. Questo è il meglio che possiamo fare con questo problema, IMHO. – Roman

0

dati modifica ha un sbagliato atmosfera, basta creare un nuovo Iterable (o raccolta) e aggiungere gli elementi che si desidera conservare ad essa, le altre volte sono perso nel ciclo for ((tipo **

+0

voi non avete mai sentito parlare di programmazione funzionale – fringd

1

Se la raccolta è ragionevolmente piccola, in alternativa puoi usare una copia della raccolta per iterare se vuoi essere in grado di rimuovere elementi in modo da non dover agire come se hai due collezioni:

for(T e : collection.clone()) 
    if(e.shouldBeRemoved()) 
     collection.remove(); 

Ancora meglio, Apache CollectionUtils (e probabilmente esiste un'alternativa a Google e un'alternativa generica) fornisce filter(java.util.Collection collection, Predicate predicate). Questo esempio restituisce l'intera lista. È possibile memorizzare un predicato per il riutilizzo.

CollectionUtils.filter(collection, new Predicate(){ 
     boolean evaluate(Object object){return true;} 
    }); 
1

Lei ha ragione, utilizzando un Iterator supporta la capacità di rimuovere un oggetto da una raccolta fonte in modo sicuro, chiamando rimuovere() sul Iterator stesso. Il punto qui è di evitare una ConcurrentModifiedException che implica che una collezione è stata modificata mentre un Iterator era aperto contro di essa. Alcune raccolte ti consentono di rimuovere o aggiungere elementi a una raccolta mentre esegui un'iterazione su di essa, ma chiamare remove() su Iterator è una pratica più sicura.

Ma Iterator supporta un derivato e più potente cugino ListIterator, disponibile solo da liste, supporta sia aggiunta e la rimozione da un elenco durante l'iterazione, così come lo scorrimento bidirezionale tramite liste.

Problemi correlati