2013-04-05 8 views
12

Ieri, quando stavo rispondendo a mettere in discussione getting ConcurrentModificationException error while using iterator and remove ho aggiunto un avviso cheAbbiamo mai avuto bisogno di usare Iterators su ArrayList?

Non è una buona idea usare iteratori quando si dispone di ArrayLists.

Non è necessario comprendere a fondo questa domanda per rispondere su quello.

Lì, ho ricevuto due commenti che ho sbagliato.

I miei argomenti:

  1. Il codice è molto meno leggibile con iteratori.

  2. Esiste la possibilità di aumentare ConcurrentModificationException che è difficile eseguire il debug.

Potete spiegare, per favore?

Domanda: Abbiamo mai avuto bisogno di usare Iterators su ArrayList?

UPD

Questo è di circa esplicitamente usando Iterator.

+2

Dipende da cosa si intende "utilizzando gli iteratori". Ogni volta che fai 'for (Integer x: listOfInts)', stai implicitamente utilizzando un iteratore. –

+0

@Oli Charlesworth, grazie per avermelo fatto notare! Sì, intendo iteratori espliciti. – Vitaly

risposta

19

Un grande caso di utilizzo degli iteratori con ArrayList è quando si desidera rimuovere elementi mentre si itera. Hai solo tre soluzioni sicure:

  • utilizzare un iteratore e il suo metodo di remove
  • copiare gli elementi che si desidera conservare in un altro elenco
  • giungla con indici

Dando per scontato che non lo fai add durante l'iterazione, utilizzando l'iteratore è un mezzo per evitare il ConcurrentModificationException.

L'argomento di leggibilità è soggettivo. Personalmente non trovo un iteratore dichiarato in modo chiaro meno leggibile. E non importa in quanto l'iteratore è il modo sicuro per iterare e rimuovere allo stesso tempo.

+1

L'unica buona ragione per me: "usa un iteratore e il suo metodo di rimozione". Se qualcuno vuole solo iterare e rimuovere elementi non necessari dall'elenco. Grazie. – Vitaly

+0

@dystroy mi spiace di averlo aperto, ma non capisco perché sia ​​necessario utilizzare un Iterator per rimuovere un elemento da ArrayList? – 12rad

+0

@Vitaly Ho eseguito un test rapido \t Elenco a = new ArrayList (); \t \t \t a.add ("a"); \t \t \t a.add ("b"); \t \t \t a.add ("c"); \t \t \t a.add ("d"); \t \t \t a.add ("e"); \t \t \t a.remove ("b"); e sembra funzionare. – 12rad

2

Sì, abbiamo bisogno. ArrayList è solo un'implementazione dell'interfaccia List, così spesso il tuo codice elabora un elenco e non sa nemmeno che si tratta di un ArrayList. Inoltre, la nuova sintassi for-loop utilizza internamente gli iteratori.

+0

Grazie. è su ArrayList. – Vitaly

0

Probabilmente stai parlando di usare esplicitamente un iteratore (poiché: l'operatore usa anche l'iteratore dietro le quinte).

Si supponga di voler inserire due "puntatori" nell'array ma la velocità dipende dai valori effettivi degli elementi. Come faresti questo senza usare esplicitamente gli iteratori (e senza elemento Naturalmente).

Per esempio (pseudo codice):

element1 = first element; 
element2 = first element; 
while(element1.hasNext && element2.hasNext) 
{ 
    if(element1 * 2 < element) 
    { 
     element2 = element2.next; 
    } 
    else 
    { 
     element1 = element1.next; 
    } 

    //do something with the pair of elements 
} 
+0

Grazie, possiamo usare ArrayList.elementAt(), perché no? :) Potresti chiarire cosa intendi con "la velocità dipende dai valori effettivi degli elementi"? – Vitaly

+0

@Vitaly Perché allora il tuo codice è 'ArrayList '-specifico, invece di essere generale a qualsiasi' Elenco. – EJP

+0

Non è "il mio codice" :) e le domande riguardano se sappiamo che è ArrayList. – Vitaly

-1

Il codice è molto meno leggibile con iteratori.

Questa è interamente la vostra opinione e non la condivido.

Vi è la possibilità di aumentare ConcurrentModificationException che è difficile eseguire il debug.

Probabilmente esiste se si utilizzano Iteratori o meno. Questa eccezione ti dice qualcosa di utile sul tuo codice che altrimenti potresti perdere completamente, il che è ancora più difficile da eseguire il debug.

Personalmente preferisco essere in grado di scrivere esattamente il codice tra ArrayList e LinkedList e che il compilatore o l'API implementino i dettagli.

La morale è che non si dovrebbe passare la propria opinione non supportata come fatto stabilito.

1

Controllare questo post: http://www.xyzws.com/javafaq/what-is-the-advantage-of-using-an-iterator-compared-to-the-getindex-method/19

Utilizzando iteratore eviterà l'errore di usare get (indice) sul LinkedList (estremamente lento). Ha senso quando l'implementazione della lista è sconosciuta, basta usare iteratore. Per quanto riguarda ArrayList, l'utilizzo di iteratore otterrà comunque le prestazioni più vicine possibili con get (indice).

Quindi è una buona pratica usare iteratore per iterare in termini di prestazioni.

7

Nessuna delle risposte sembra indicare il motivo degli iteratori. Il modello di progettazione iteratore è stato creato perché un oggetto deve avere il controllo del proprio stato (tranne forse oggetti valore con sole proprietà pubbliche).

Diciamo che abbiamo un oggetto che contiene un array e in quell'oggetto è presente un'interfaccia per aggiungere elementi a tale array. Ma bisogna fare qualcosa di simile:

class MyClass 
{ 
    private ArrayList<Item> myList; 

    public MyClass() 
    { 
     myList = new ArrayList(); 
    } 

    public addItem(Item item) 
    { 
     item.doSomething(); // Lets say that this is very important before adding the item to the array. 
     myList.add(item); 
    } 
} 

Ora, se ho avuto questo metodo nella classe di cui sopra:

public ArrayList getList() 
{ 
    return myList; 
} 

Qualcuno potrebbe ottenere il riferimento a MyList attraverso questo metodo e aggiungere elementi alla matrice, senza chiamata item.doSomething(); Ecco perché non si dovrebbe restituire un riferimento alla matrice, ma invece restituire il suo iteratore. Si può ottenere qualsiasi elemento dall'array, ma non può manipolare l'array originale. Quindi l'oggetto MyClass ha ancora il controllo del proprio stato.

Questa è la vera ragione per cui sono stati inventati gli iteratori.

Problemi correlati