wake-up-neo.com

Warum müssen wir den Iterator für ArrayList in Java verwenden?

Ich las die erwähnte Antwort auf die Frage " Müssen wir jemals Iteratoren für ArrayList verwenden? ".

In der Antwort gab der Benutzer etwa Folgendes an: "Ein großer Anwendungsfall für Iteratoren mit ArrayLists ist, wenn Sie Elemente während der Iteration entfernen möchten".

Dies kann sogar erreicht werden, wenn die Entfernungsmethode von ArrayList in Java verwendet wird. Meine Frage ist, warum wir einen Iterator in ArrayList brauchen. 

Betrachten Sie den Code: 

import Java.util.*;
public class ocajp66 {
    public static void main(String[] args) {
        ArrayList a = new ArrayList();
        for (int i = 0; i < 10; i++) {
            a.add(i);
        }
        System.out.printf("BEFORE ITERATOR\n");
        for (int i = 0; i < a.size(); i++) {
            System.out.printf("I:%d\n", a.get(i));
        }
        System.out.printf("AFTER ITERATOR\n");
        Iterator i = a.iterator();
        while (i.hasNext()) {
            System.out.printf("I:%d\n", i.next());
        }
    }
}

Kann jemand die Bedeutung des Iterators erklären? Es wäre wunderbar, wenn Sie mich mit Code erklären könnten.

32
Karthik Rk

Wie Sie bereits gesagt haben, wird der Iterator verwendet, wenn Sie Sachen entfernen möchten, während Sie den Inhalt des Arrays durchlaufen. Wenn Sie keinen Iterator verwenden, sondern lediglich eine for-Schleife haben, verwenden Sie die remove-Methode, um Ausnahmen zu erhalten, da sich der Inhalt des Arrays ändert, während Sie durchlaufen. Beispiel: Sie denken vielleicht, dass die Array-Größe am Anfang der for-Schleife 10 ist, aber es wird nicht der Fall sein, wenn Sie Sachen entfernen. Wenn Sie also die letzten Schleifen erreichen, wird es wahrscheinlich IndexOutofBoundsException usw. geben.

49
Dev Blanked

Es ist klar, dass eine ArrayList-ähnliche API ohne die iterator()-Methode funktionieren könnte. Eine ArrayList ist jedoch eine Collection und die iterator()-Methode ist in der Collection-Schnittstelle definiert ... also ArrayListhat, um sie zu implementieren.

Beim Löschen aus einem ArrayList geht es darum, dass die Indizierung einige Überlegungen erfordert:

    for (int i = 0; 
         i < a.size(); // Hoist this at your peril
         i++) {
        if (a.get(i) == something) {
            a.remove(i);
            i--;  // Leave this out at your peril
        }
    }

Und es wird noch schlimmer, wenn Sie das Listenelement in einer aus der Schleife aufgerufenen Methode entfernen müssen. Die Methode muss dann sagen, dass sie ein Element entfernt hat, damit der Aufrufer den Schleifenindex anpassen kann.

Ein dritter Grund, warum iterator eine gute Sache für ArrayList ist, besteht darin, dass Sie die for (type var : iterable) ...-Syntax von Java 5 verwenden können.

Die letzte Zeile ist, dass Sie keine müssen Iteratoren für ArrayList-Instanzen verwenden. Wenn Sie nicht wollen, dann nicht.

14
Stephen C

Dies ist ein Beispiel dafür, wie es möglich ist, die gewünschten Ergebnisse auf verschiedene Weise zu erzielen. Diese Art der Redundanz gilt nicht nur für Java.

  • for (int i = 0; i <meinArray.length; i ++) {...}

Diese Syntax wurde in sehr frühen Java-Versionen eingeführt. Es durchläuft ein gewöhnliches Java-Array in einer for {} -Schleife. Dies ist im Allgemeinen sicher, da Java-Arrays eine feste Länge haben. Ausnahmen von "Index Out of Bounds" sind daher nicht möglich.

  • for (int i = 0; i <meineArrayList.size (); i ++ {...}

Diese Syntax spiegelt eine spätere Version von Java wider, nach Einführung der Collections-API, mit der ArrayList eingeführt wurde. Klassen, die die Collection-Schnittstelle implementieren, wie oben bereits erwähnt, müssen einen Iterator implementieren, müssen ihn aber nicht verwenden. Diese for {} -Schleife gilt nicht, aber die Gefahr besteht darin, dass ArrayLists keine feste Größe haben. Wenn es im Hauptteil Ihrer for-Schleife schrumpfen sollte, kann dies zu Ausnahmen führen.

  • für (MyArrayType t: myArrayList) {}

Diese Syntax wurde auch in einer späteren Version von Java veröffentlicht. Es wird die erweiterte for-Schleife genannt. Jede Auflistungsklasse, die einen Iterator durch Implementierung der Iterable-Schnittstelle bereitstellt, kann diese Syntax nutzen. Dies ermöglicht das Durchlaufen von Elementen in einer Sammlung, ohne dass ein Iterator explizit instanziiert werden muss. Eine beliebte Methode, um dies in einer JavaFX-Anwendung zu verwenden, besteht darin, eine Reihe von Steuerelementen zu durchlaufen, um eine Eigenschaft auf einen Wert festzulegen, z. So setzen Sie den Inhalt einer Gruppe von TextFields zurück:

for (TextField tf : new TextField[] { txtf1, txtf2, txtf3, txtfa, txtfb, txtfc}) {
    tf.setText("");
}
  • while (myCollectionIterator.hasNext ()) {}

Sie können einen Iterator immer explizit instanziieren. Dies ist sicher zu verwenden, wenn sich die Sammlungsgröße ändert (von den eigenen Methoden der Sammlung). Es ist richtig zu sagen, dass der Iterator eher eine Eigenschaft der Iterable-Schnittstelle ist als eine Funktion der Java-Kernsprache. Dank späterer Java-Versionen können Sie es jedoch weiterhin als sprachähnliche Funktion (in der erweiterten for-Schleife) verwenden.

Diese Konstrukte bieten Redundanz, sind aber nicht identisch. Es gibt Nuancen von jedem, die es ermöglichen, zu einem bestimmten Zeitpunkt besonders nützlich zu sein. Sie sollten alle verwenden.

6
scottb

F: Warum brauchen wir einen Iterator in ArrayList?

Wir tun es nicht - genau wie Sie in Ihrem Code gezeigt haben, können Sie eine ArrayList ohne Iterator iterieren und Kernoperationen ausführen. Aber es ist ein schönes Feature.

F: Kann jemand die Bedeutung des Iterators erklären?

Neben dem Designwert konnte ich die Fail-Fast-Funktion sehen. Ich zitiere diesen Absatz aus der ArrayList-Dokumentation :

Die Iteratoren, die vom Iterator und vom listIterator dieser Klasse zurückgegeben werden Methoden sind fail-fast: wenn die Liste strukturell an einem beliebigen .__ geändert wird. Zeit, nachdem der Iterator erstellt wurde, auf irgendeine Weise, außer durch die Wenn Iterators eigene Methoden zum Entfernen oder Hinzufügen von Iteratoren verwendet werden, wirft der Iterator eine ConcurrentModificationException. Angesichts der gleichzeitigen Bei einer Änderung fällt der Iterator schneller und sauberer aus als mit willkürliches, nicht deterministisches Verhalten zu einem unbestimmten Zeitpunkt riskieren in der Zukunft.

Sie haben nach Code gesucht. Die Iterator-Implementierung von ArrayList kann hier angezeigt werden: ArrayList.Java .

1
Jops

Wenn Sie für Ihre Frage die Methode list.remove() anstelle von iterator.remove() verwenden, wird IndexOutOfBoundsException ausgelöst. 

list.remove() ist sicher zu verwenden, wenn Sie die break-Anweisung einsetzen, sobald Sie ein bestimmtes Objekt/einen bestimmten Index entfernt haben, so dass es ohne Ausnahme (wie IndexOutOfBoundsException) aus der Schleife entfernt wird

Folgender Iterator-Code kann immer noch ConcurrentModificationException werfen, wenn der Iterator EVEN in synchronized environment verwendet wird.

List<String> empNames = new ArrayList<String>();
        synchronized (empNames) {
            Iterator<String> iterator = empNames.iterator();
            while (iterator.hasNext()) {
                iterator.next();
                empNames.add("Another Name"); // throws
                // ConcurrentModificationException
            }
        }
0
AmitG