


Detaillierte Erläuterung des Beispielcodes des Iterators im Java Collection Framework
Dieser Artikel bietet Ihnen hauptsächlich eine kurze Einführung in die relevanten Informationen zum Iterator im Java-Sammlungsframework. Er hat einen bestimmten Referenzwert.
Array-Daten in Java können abgerufen werden Index, was ist mit Objekten? Auch über den Index? Heute analysieren wir die Methode iteration-Iterator zum Abrufen von Sammlungsobjekten in Java-Sammlungen.
Dieser Artikel analysiert hauptsächlich den Iterator-Teil im Java-Sammlungs-Framework, Iterator. Die Quellcode-Analyse basiert auf JDK1.8, Analysetool, AndroidStudio. Bitte korrigieren Sie mich, wenn die Artikelanalyse Mängel aufweist.
1. Einführung
Wir verwenden häufig die von JDK bereitgestellte Iterationsschnittstelle, um Java-Sammlungen zu iterieren.
Iterator iterator = list.iterator(); while(iterator.hasNext()){ String string = iterator.next(); //do something }
Das Obige ist die grundlegende Vorlage, die von Iteratoren verwendet wird. Tatsächlich können wir Iteration einfach als Durchquerung verstehen, eine standardisierte Methodenklasse zum Durchlaufen aller Objekte in verschiedenen Containern. Es steuert immer den Iterator und sendet ihm die Befehle „vorwärts“, „rückwärts“ und „aktuelles Element abrufen“, um indirekt die gesamte Sammlung zu durchlaufen. In Java ist Iterator eine Schnittstelle, die nur Grundregeln für die Iteration bereitstellt:
public interface Iterator<E> { //判断容器内是否还有可供访问的元素 boolean hasNext(); //返回迭代器刚越过的元素的引用,返回值是 E E next(); //删除迭代器刚越过的元素 default void remove() { throw new UnsupportedOperationException("remove"); } }
Das Obige ist die Grunddeklaration eines Iterators. Wir analysieren ihn anhand spezifischer Sammlungen.
2. Klassifizierung der Sammlung
2.1 Iterator von ArrayList
Durch die Analyse des Quellcodes von ArrayList können wir erkennen, dass darin zuerst eine interne Klasse definiert ist ArrayList Itr, diese innere Klasse implementiert die Iterator-Schnittstelle wie folgt:
private class Itr implements Iterator<E> { //.... }
Die innere Klasse implementiert die Iterator-Schnittstelle, und der Iterator von ArrayList gibt seine innere Klasse Itr zurück, also wir Sehen Sie sich hauptsächlich an, wie Itr implementiert wird.
public Iterator<E> iterator() { return new Itr(); }
Als nächstes analysieren wir die Implementierung seiner internen Klasse Itr.
private class Itr implements Iterator<E> { protected int limit = ArrayList.this.size; int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; public boolean hasNext() { return cursor < limit; } @SuppressWarnings("unchecked") public E next() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); int i = cursor; if (i >= limit) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); if (modCount != expectedModCount) throw new ConcurrentModificationException(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; limit--; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } @Override @SuppressWarnings("unchecked") public void forEachRemaining(Consumer<? super E> consumer) { Objects.requireNonNull(consumer); final int size = ArrayList.this.size; int i = cursor; if (i >= size) { return; } final Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) { throw new ConcurrentModificationException(); } while (i != size && modCount == expectedModCount) { consumer.accept((E) elementData[i++]); } // update once at end of iteration to reduce heap write traffic cursor = i; lastRet = i - 1; if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
Als Erstes analysieren wir die definierte -Variable:
protected int limit = ArrayList.this.size; int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount;
Unter diesen ist „Limit“ die Größe der aktuellen ArrayList und der Cursor stellt das nächste Element dar . Index und lastRet ist der Index des vorherigen Elements. Wenn nicht, ist die Rückgabe von -1 von geringem Nutzen. Wir werden dann analysieren und sehen, wie wir feststellen können, ob es während der Iteration nachfolgende Elemente gibt.
public boolean hasNext() { return cursor < limit; }
Es ist ganz einfach, festzustellen, ob der Index des nächsten Elements die Kapazität des Arrays erreicht hat. Wenn dies der Fall ist, ist es vorbei.
Als nächstes analysieren wir die Methode zum Erhalten des Elements des aktuellen Index
public E next() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); int i = cursor; if (i >= limit) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; }
Warum müssen wir modCount in der nächsten Methode bestimmen? Das heißt, es wird verwendet, um zu bestimmen, ob die Sammlung während des Durchlaufprozesses geändert wurde. modCount wird verwendet, um die Anzahl der Änderungen der ArrayList-Sammlung aufzuzeichnen. Es wird auf 0 initialisiert. Immer wenn die Sammlung geändert wird (Änderungen an der Struktur, interne Aktualisierungen werden nicht gezählt), wie z. B. Hinzufügen, Entfernen und andere Methoden, gilt modCount + 1 Wenn also modCount unverändert bleibt, bedeutet dies, dass der Sammlungsinhalt nicht geändert wurde. Dieser Mechanismus wird hauptsächlich zur Implementierung des Schnellfehlermechanismus der ArrayList-Sammlung verwendet. Unter den Java-Sammlungen verfügt ein großer Teil der Sammlungen über Schnellfehlermechanismen. Um sicherzustellen, dass während des Durchlaufvorgangs keine Fehler auftreten, sollten wir daher sicherstellen, dass während des Durchlaufvorgangs keine strukturellen Änderungen an der Sammlung vorgenommen werden (außer natürlich bei der Entfernungsmethode). Wenn ein ungewöhnlicher Fehler auftritt, sollten wir dies sorgfältig prüfen ob das Programm Fehler hat statt Keine Verarbeitung erfolgt nach Catch. Der obige Code ist relativ einfach, er gibt lediglich den Array-Wert am Index zurück.
Bei der Iterationsmethode von ArrayList wird hauptsächlich der Wert des Index beurteilt und mit der Größe des Arrays verglichen, um festzustellen, ob keine Daten zum Durchlaufen vorhanden sind, und dann werden die Werte in abgerufen Das Array wiederum erfasst hauptsächlich die zugrunde liegende Implementierung.
Als nächstes analysieren wir die Iterator-Methode von HashMap. Andere Methoden sind ähnlich, solange Sie die zugrunde liegende Implementierung verstehen.
2.2 HashMap's Iterator
In HashMap gibt es auch eine Klasse, die die Iterator-Schnittstelle implementiert, aber es ist nur eine abstrakte Klasse, Werfen wir einen Blick darauf wie es umgesetzt wird.
private abstract class HashIterator<E> implements Iterator<E> { HashMapEntry<K,V> next; // next entry to return int expectedModCount; // For fast-fail int index; // current slot HashMapEntry<K,V> current; // current entry HashIterator() { expectedModCount = modCount; if (size > 0) { // advance to first entry HashMapEntry[] t = table; while (index < t.length && (next = t[index++]) == null) ; } } public final boolean hasNext() { return next != null; } final Entry<K,V> nextEntry() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); HashMapEntry<K,V> e = next; if (e == null) throw new NoSuchElementException(); if ((next = e.next) == null) { HashMapEntry[] t = table; while (index < t.length && (next = t[index++]) == null) ; } current = e; return e; } public void remove() { if (current == null) throw new IllegalStateException(); if (modCount != expectedModCount) throw new ConcurrentModificationException(); Object k = current.key; current = null; HashMap.this.removeEntryForKey(k); expectedModCount = modCount; } }
In ähnlicher Weise definiert es auch eine Variable
HashMapEntry<K,V> next; // next entry to return int expectedModCount; // For fast-fail int index; // current slot HashMapEntry<K,V> current; // current entry
next, die den nächsten Eintragsknoten darstellt. ExpectedModCount wird auch verwendet, um den geänderten Status zu bestimmen Schneller Fail-Mechanismus für Sammlungen. Der Index stellt den aktuellen Index dar, und der Knoteneintrag wird durch den aktuellen Index dargestellt. Schauen wir uns an, wie ermittelt wird, ob für das nächste Element ein Wert vorhanden ist.
public final boolean hasNext() { return next != null; }
Es ist sehr einfach festzustellen, ob next null ist. Wenn es null ist, bedeutet dies, dass keine Daten vorhanden sind.
Analysieren Sie dann die Methode zur Gewinnung von Elementen
final Entry<K,V> nextEntry() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); HashMapEntry<K,V> e = next; if (e == null) throw new NoSuchElementException(); // 一个Entry就是一个单向链表 // 若该Entry的下一个节点不为空,就将next指向下一个节点; // 否则,将next指向下一个链表(也是下一个Entry)的不为null的节点。 if ((next = e.next) == null) { HashMapEntry[] t = table; while (index < t.length && (next = t[index++]) == null) ; } current = e; return e; }
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Beispielcodes des Iterators im Java Collection Framework. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

Anleitung zum TimeStamp to Date in Java. Hier diskutieren wir auch die Einführung und wie man Zeitstempel in Java in ein Datum konvertiert, zusammen mit Beispielen.

Kapseln sind dreidimensionale geometrische Figuren, die aus einem Zylinder und einer Hemisphäre an beiden Enden bestehen. Das Volumen der Kapsel kann berechnet werden, indem das Volumen des Zylinders und das Volumen der Hemisphäre an beiden Enden hinzugefügt werden. In diesem Tutorial wird erörtert, wie das Volumen einer bestimmten Kapsel in Java mit verschiedenen Methoden berechnet wird. Kapselvolumenformel Die Formel für das Kapselvolumen lautet wie folgt: Kapselvolumen = zylindrisches Volumenvolumen Zwei Hemisphäre Volumen In, R: Der Radius der Hemisphäre. H: Die Höhe des Zylinders (ohne die Hemisphäre). Beispiel 1 eingeben Radius = 5 Einheiten Höhe = 10 Einheiten Ausgabe Volumen = 1570,8 Kubikeinheiten erklären Berechnen Sie das Volumen mithilfe der Formel: Volumen = π × R2 × H (4

PHP und Python haben jeweils ihre eigenen Vorteile, und die Wahl sollte auf Projektanforderungen beruhen. 1.PHP eignet sich für die Webentwicklung mit einfacher Syntax und hoher Ausführungseffizienz. 2. Python eignet sich für Datenwissenschaft und maschinelles Lernen mit präziser Syntax und reichhaltigen Bibliotheken.

PHP ist eine Skriptsprache, die auf der Serverseite weit verbreitet ist und insbesondere für die Webentwicklung geeignet ist. 1.PHP kann HTML einbetten, HTTP -Anforderungen und Antworten verarbeiten und eine Vielzahl von Datenbanken unterstützt. 2.PHP wird verwendet, um dynamische Webinhalte, Prozessformdaten, Zugriffsdatenbanken usw. mit starker Community -Unterstützung und Open -Source -Ressourcen zu generieren. 3. PHP ist eine interpretierte Sprache, und der Ausführungsprozess umfasst lexikalische Analyse, grammatikalische Analyse, Zusammenstellung und Ausführung. 4.PHP kann mit MySQL für erweiterte Anwendungen wie Benutzerregistrierungssysteme kombiniert werden. 5. Beim Debuggen von PHP können Sie Funktionen wie error_reporting () und var_dump () verwenden. 6. Optimieren Sie den PHP-Code, um Caching-Mechanismen zu verwenden, Datenbankabfragen zu optimieren und integrierte Funktionen zu verwenden. 7

Java ist eine beliebte Programmiersprache, die sowohl von Anfängern als auch von erfahrenen Entwicklern erlernt werden kann. Dieses Tutorial beginnt mit grundlegenden Konzepten und geht dann weiter zu fortgeschrittenen Themen. Nach der Installation des Java Development Kit können Sie das Programmieren üben, indem Sie ein einfaches „Hello, World!“-Programm erstellen. Nachdem Sie den Code verstanden haben, verwenden Sie die Eingabeaufforderung, um das Programm zu kompilieren und auszuführen. Auf der Konsole wird „Hello, World!“ ausgegeben. Mit dem Erlernen von Java beginnt Ihre Programmierreise, und wenn Sie Ihre Kenntnisse vertiefen, können Sie komplexere Anwendungen erstellen.
