2013-01-07 15 views
5

Secondo Sun,Collection - Iterator.remove() vs Collection.remove()

"Iterator.remove è l'unico modo sicuro per modificare una raccolta durante iterazione, il comportamento è specificato se il sottostante la raccolta è modificata in qualsiasi altro modo mentre è in corso l'iterazione. "

Ho due domande:

  1. Ciò che rende questa operazione "Iterator.remove()" stabile rispetto agli altri?
  2. Perché hanno fornito un metodo "Collection.remove()" se non sarà utile nella maggior parte dei casi d'uso?

risposta

5

Se stai iterazione di una collezione e l'uso:

Collection.remove() 

è possibile ottenere gli errori di runtime (in particolare ConcurrentModifcationException) perché stai cambiando lo stato dell'oggetto utilizzato in precedenza per costruire la serie esplicito di chiamate necessario per completare il ciclo.

se si utilizza:

Iterator.remove() 

dici il runtime che si desidera modificare la raccolta Sottostante e rivalutare la serie esplicita di chiamate necessarie per completare il ciclo.

8

Come la documentazione che hai citato chiaramente afferma,

Iterator.remove è l'unico modo sicuro per modificare una raccolta durante l'iterazione

(enfasi aggiunta)

Durante l'utilizzo di iteratore, non è possibile modificare la raccolta, tranne chiamando Iterator.remove().

Se non si sta iterando la raccolta, si utilizzerà Collection.remove().

12

Prima di tutto, Collection.remove() è molto utile. È applicabile in molti casi d'uso, probabilmente più di Iterator.remove().

Tuttavia, quest'ultimo risolve un problema specifico: consente di modificare la raccolta durante l'iterazione su di esso.

Il problema risolto da Iterator.remove() è illustrata di seguito:

List<Integer> l = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4)); 
    for (int el : l) { 
     if (el < 3) { 
      l.remove(el); 
     } 
    } 

Questo codice è valido in quanto l.remove() viene chiamato durante l'iterazione su l.

Quello che segue è il modo corretto di scrivere:

Iterator<Integer> it = l.iterator(); 
    while (it.hasNext()) { 
     int el = it.next(); 
     if (el < 3) { 
      it.remove(); 
     } 
    } 
+0

Ho messo un'istruzione 'break' dopo' l.remove (e1) 'e VM non lanciano un'eccezione usando Java 1.6 – Kurapika

1

Ciò che rende questa operazione "Iterator.remove()" stabile rispetto agli altri?

Significa che l'iteratore sa che hai rimosso l'elemento in modo che non generi ConcurrentModifcationException.

Perché hanno fornito un metodo "Collection.remove()" se non è utile nella maggior parte dei casi d'uso?

In genere si utilizza Map.remove() o Collection.remove() in quanto può essere molto più efficiente di iterare su tutti gli oggetti.Se si rimuove durante l'iterazione, spesso sospetto che si debbano utilizzare raccolte diverse.

0
  1. È solo una scelta di design. Sarebbe stato possibile specificare un comportamento diverso (vale a dire che l'iteratore deve saltare i valori rimossi da Collection.remove()), ma ciò avrebbe reso l'implementazione della struttura di raccolta molto più complessa. Quindi la scelta di lasciarlo non specificato.

  2. È abbastanza utile. Se conosci l'oggetto che vuoi rimuovere, perché iterare?

0

Da quanto ho capito, Collection.remove (int index) restituirà anche l'oggetto rimosso. Iterative.remove() non lo farà.