2013-04-05 7 views
12

Gestern, als ich die Beantwortung getting ConcurrentModificationException error while using iterator and remove in Frage habe ich einen Hinweis, dassMüssen wir jemals Iteratoren in ArrayList verwenden?

Es ist keine gute Idee, Iteratoren zu verwenden, wenn Sie Arraylisten haben.

Sie müssen diese Frage nicht tief verstehen, um darauf zu antworten.

Dort habe ich zwei Kommentare, die ich falsch liege.

Meine Argumente:

  1. Der Code viel weniger lesbar mit Iteratoren ist.

  2. Es gibt eine Möglichkeit, ConcurrentModificationException auszulösen, die schwer zu debuggen ist.

Können Sie bitte erklären?

Frage: Müssen wir jemals Iteratoren auf ArrayList verwenden?

UPD

Hier geht es um explizit Iterator wird.

+2

Hängt davon ab, was Sie unter "Iteratoren verwenden" verstehen. Jedes Mal, wenn Sie 'for (Integer x: listOfInts)' ausführen, verwenden Sie implizit einen Iterator. –

+0

@Oli Charlesworth, vielen Dank für den Hinweis! Ja, ich meine explizite Iteratoren. – Vitaly

Antwort

19

Ein großer Anwendungsfall von Iteratoren mit ArrayLists ist, wenn Sie Elemente während der Iteration entfernen möchten. Sie haben nur drei sichere Lösungen:

  • Verwendung ein Iterator und seine remove Methode
  • die Elemente kopieren Sie in einer anderen Liste
  • Dschungel mit Indizes

Angenommen, Sie nicht behalten wollen add während der Iteration, mit dem Iterator ist ein Mittelwert zu vermeiden die ConcurrentModificationException.

Das Lesbarkeitsargument ist subjektiv. Ich persönlich finde einen sauber deklarierten Iterator weniger lesbar. Und es ist nicht wirklich wichtig, da der Iterator der sichere Weg ist, gleichzeitig zu iterieren und zu entfernen.

+1

Der einzige gute Grund für mich: "Verwenden Sie einen Iterator und seine Methode entfernen". Wenn jemand nur unnötige Elemente aus der Liste iterieren und entfernen möchte. Vielen Dank. – Vitaly

+0

@dystroy Entschuldigung, das zu öffnen, aber ich verstehe nicht, warum Sie einen Iterator verwenden müssen, um ein Element aus der ArrayList zu entfernen? – 12rad

+0

@Vitaly Ich habe einen schnellen Test \t Liste a = neue 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.entfernt ("b"); und es scheint zu funktionieren. – 12rad

2

Ja, wir brauchen. ArrayList ist nur eine Implementierung der List-Schnittstelle, also wird Ihr Code oft eine Liste verarbeiten und nicht einmal wissen, dass es sich um eine ArrayList handelt. Außerdem verwendet die neue For-Loop-Syntax intern Iteratoren.

+0

Danke ist über ArrayList. – Vitaly

0

Sie sprechen wahrscheinlich davon, explizit einen Iterator zu verwenden (da der Operator: auch den Iterator hinter den Kulissen verwendet).

Angenommen, Sie möchten zwei "Zeiger" über das Array laufen lassen, aber die Geschwindigkeit hängt von den tatsächlichen Elementwerten ab. Wie würden Sie dies tun, ohne explizit Iteratoren (und natürlich ohne elementAt) zu verwenden.

Beispiel (Pseudocode):

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

Danke.Wir können ArrayList.elementAt(), warum nicht? :) Könnten Sie klären, was meinst du mit "die Geschwindigkeit hängt von den tatsächlichen Element Werte"? – Vitaly

+0

@Vitaly Da ist dann Ihr Code 'ArrayList '-speziell, anstatt allgemein zu irgendeiner' Liste.' zu sein – EJP

+0

Es ist nicht "mein Code" :) und die Fragen sind ungefähr, wenn wir wissen, dass es ArrayList ist. – Vitaly

-1

Der Code ist viel weniger lesbar mit Iteratoren.

Das ist ganz Ihrer Meinung, und ich teile es nicht.

Es gibt eine Möglichkeit, ConcurrentModificationException auszulösen, die schwer zu debuggen ist.

Das existiert möglicherweise, ob Sie Iteratoren verwenden oder nicht. Diese Exception sagt Ihnen etwas Nützliches über Ihren Code, das Sie sonst vielleicht ganz vermissen würden, was noch schwieriger zu debuggen ist.

Persönlich bevorzuge ich in der Lage, genau den Code zwischen ArrayList und LinkedList zu schreiben, und den Compiler oder die API die Details implementieren zu lassen.

Die Moral ist, dass Sie Ihre eigene nicht unterstützte Meinung als feststehende Tatsache nicht weitergeben sollten.

1

Überprüfen Sie diesen Eintrag: http://www.xyzws.com/javafaq/what-is-the-advantage-of-using-an-iterator-compared-to-the-getindex-method/19

Iterator wird den Fehler, mit get (Index) auf LinkedList (extrem langsam) vermeiden. Es macht Sinn, wenn die Implementierung der Liste unbekannt ist, benutze einfach den Iterator. In Bezug auf ArrayList erreicht die Verwendung von Iterator immer noch die bestmögliche Leistung mit get (index).

Es ist also eine gute Übung, Iterator für die Iteration in Bezug auf die Leistung zu verwenden.

7

Keine der Antworten scheint den Grund für Iteratoren anzugehen. Das Iterator-Entwurfsmuster wurde erstellt, da ein Objekt die Kontrolle über seinen eigenen Status haben sollte (außer vielleicht Werteobjekte mit nur öffentlichen Eigenschaften).

Nehmen wir an, wir haben ein Objekt, das ein Array enthält, und Sie haben eine Schnittstelle in diesem Objekt, um Elemente zu diesem Array hinzuzufügen. Aber Sie haben so etwas tun:

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

Nun, wenn ich oben in der Klasse diese Methode hatte:

public ArrayList getList() 
{ 
    return myList; 
} 

Jemand könnte die Referenz erhalten durch diese Methode myList und Hinzufügen von Elementen zum Array, ohne Aufruf item.doSomething(); Deshalb sollten Sie keinen Verweis auf das Array zurückgeben, sondern stattdessen seinen Iterator zurückgeben. Man kann ein beliebiges Element aus dem Array abrufen, aber es kann das ursprüngliche Array nicht manipulieren. Das MyClass-Objekt hat also immer noch die Kontrolle über seinen eigenen Status.

Dies ist der wahre Grund, warum Iteratoren erfunden wurden.

Verwandte Themen