Beim Lernen der Sammlung in Java wird angemerkt, dass die Sammlung der Sammlung hierarchie Root Interface die iterable <T> -Kinterface (das sich im Java.lang -Paket befindet) implementiert, mit dem Objekte das Ziel der "Foreach" -Anweisung werden können. Der einzige Weg in dieser Schnittstelle besteht darin, einen Iterator zurückzugeben, der auf einem Satz von T-Typ-Elementen iteriert.
1. Iterator
Schnittstelle: Iterator <T>
public interface iterator <e> {boolean hasNext (); E als nächstes (); Hohlraum entfernen (); }Wenn Sie sich die Iterator -Schnittstellen -API ansehen, können Sie wissen, dass dies ein Iterator ist, der über die Sammlung iteriert. Mit dem Iterator kann der Anrufer Elemente aus der Sammlung entfernen, auf die der Iterator während der Iteration mit gut definierter Semantik vermittelt wird.
Es ist besonders bemerkenswert, dass diese Iterator -Methode REMET () verwendet wird: Entfernen Sie das letzte vom Iterator zurückgegebene Element aus der Sammlung, auf die der Iterator vermittelt wurde (optionaler Vorgang). Diese Methode kann nur einmal pro Anruf als nächstes aufgerufen werden. Wenn die vom Iterator hervorgehobene Sammlung auf andere Weise geändert wird, als diese Methode (Methode zu entfernen) beim Iterieren aufzurufen, ist das Verhalten des Iterators ungewiss. Beim Entwerfen der Iterator -Schnittstelle hat der Schnittstellendesigner darauf hingewiesen, dass bei der Iterierung, wenn die REME () -Methode mit Ausnahme des Iterators aufgerufen wird und die vom Iterator veränderte Sammlung aufgerufen wird, unsichere Konsequenzen verursacht. Was sind die Konsequenzen, abhängig von der spezifischen Implementierung des Iterators? Als Reaktion auf die möglichen Situationen dieser unsicheren Folge wurde einer davon beim Lernen an Arraylist aufgetaucht: Der Iterator löst eine Ausnahme von ConcurrentModificationException aus. Die spezifischen Ausnahmen sind im folgenden Code angezeigt:
Import Java.util.ArrayList; Import Java.util.Collection; Import Java.util.iterator; öffentliche Klasse ITARATORTEST {public static void main (String [] args) {collection <string> list = new ArrayList <string> (); list.add ("android"); list.add ("iOS"); list.add ("Windows Mobile"); Iterator <string> iterator = list.iterator (); while (iterator.hasnext ()) {String Lang = iterator.next (); list.remove (Lang); // wird die ConcurrentModificationException}}} werfen In diesem Code wird beim Ausführen eine Ausnahme von ConcurrentModificificationException ausgelöst, da wir nicht die Iterator -Methode des Iterators verwenden, um das Element während des Auslaufs des Iterators zu löschen, sondern stattdessen die REME -Methode der ArrayList () (), um die vom Iterator gezeigte Sammlung zu ändern. Dies verstößt gegen die Designprinzipien des Iterators, daher tritt eine Ausnahme auf.
Die gemeldete Abnormalität ist wie folgt:
Ausnahme in Thread "Haupt" java.util.concurrentModificationException
bei Java.util.ArrayList $ ittr.checkforcomodification (ArrayList.java:859)
bei Java.util.ArrayList $ ittr.Next (arrayList.java:831)
bei text.itaratOrst.main (itaratOstest.java:17)
2. Iterator für Schleifen und Iterator <T>
Ab Java 5 gibt es in Java eine For-Each-Schleife, mit der durch Sammlung und Array geschleudert werden kann. Mit Foreach -Schleifen können Sie die Sammlung durchqueren, ohne die HasNext () -Methode in der while -Schleife aufzurufen, ohne den Index in der traditionellen für die Schleife zu halten oder Iterator /Listiterator (eine Iterator -Implementierung in ArrayList). Die For-Each-Schleife vereinfacht den Traversalprozess einer Sammlung oder eines Arrays. Es gibt jedoch zwei Punkte, auf die Sie bei der Verwendung von Foreach -Schleifen achten müssen.
Objekte, die foreach -Loops verwenden
Bitte beachten Sie das folgende Beispiel:
import Java.util.ArrayList; öffentliche Klasse foreachTest1 {public static void main (String args []) {CustomCollection <string> mycollection = new CustomCollection <string> (); mycollection.add ("java"); mycollection.add ("scala"); MyCollection.add ("Groovy"); // Was macht dieser Code, drucken Sprache, Ausnahme oder // Zeitfehler für (String -Sprache: MyCollection) {System.out.println (Sprache); }} private Klasse CustomCollection <T> {private ArrayList <T> Bucket; public CustomCollection () {bucket = new ArrayList (); } public int size () {return bucket.size (); } public boolean isempty () {return bucket.isempty (); } public boolean enthält (t o) {return bucket.contains (o); } public boolean add (t e) {return bucket.add (e); } public boolean entfernen (t o) {return bucket.remove (o); }}} Der obige Code wird nicht kompiliert, da die CustomCollection -Klasse im Code die iterable <T> -Schinschnittstelle nicht implementiert und der in der Kompilierungsperiode angegebene Fehler wie folgt lautet:
Ausnahme im Thread "Haupt" java.lang.Error: ungelöster Kompilierungsproblem:
Kann nur über ein Array oder eine Instanz von java.lang.iterable iterieren
bei text.foreachtest1.main (foreachest1.java:15)
Tatsächlich müssen Sie bis zur Zusammenstellung nicht warten, um einen Fehler zu finden. Eclipse zeigt einen Fehler in der Foreach -Schleife an, nachdem der Code fertig ist
Aus dem obigen Beispiel kann erneut bestätigt werden, dass die Foreach -Schleife nur für Objekte anwendbar ist, die die iterable <T> -Schinschnittstelle implementieren. Da alle integrierten Sammlungsklassen die Schnittstelle von Java.util.Collection implementieren und iterable ererbt haben, um das oben genannte Problem zu lösen, können Sie die CustomCollection einfach aktivieren Die Lösung lautet wie folgt:
Import Java.util.abstractCollection; Import Java.util.ArrayList; Import Java.util.iterator; öffentliche Klasse forectestest {public static void main (String args []) {CustomCollection <string> mycollection = new CustomCollection <string> (); mycollection.add ("java"); mycollection.add ("scala"); MyCollection.add ("Groovy"); für (String -Sprache: MyCollection) {System.out.println (Sprache); }} private statische Klasse CustomCollection <T> Erweitert AbstractCollection <T> {private arrayList <T> Bucket; public CustomCollection () {bucket = new ArrayList (); } public int size () {return bucket.size (); } public boolean isempty () {return bucket.isempty (); } public boolean enthält (Objekt o) {return bucket.contains (o); } public boolean add (t e) {return bucket.add (e); } public boolean entfernen (Objekt o) {return bucket.remove (o); } @Override public iterator <t> iterator () {// Todo automatisch generierte Methode Stub return bucket.iterator (); }}}2. Die interne Implementierung der Foreach -Schleife wird ebenfalls vom Iterator implementiert.
Um die Tatsache zu überprüfen, dass die Foreach -Schleife Iterator als interne Implementierung verwendet, verwenden wir weiterhin das erste Beispiel dieses Artikels, um zu überprüfen:
public class itaratOstest {public static void main (String [] args) {collection <string> list = new ArrayList <string> (); list.add ("android"); list.add ("iOS"); list.add ("Windows Mobile"); // Beispiel1 // Iterator <String> iterator = list.iterator (); // while (iterator.hasnext ()) {// String lang = iterator.next (); // list.remove (lang); //} // Beispiel 2 für (String -Sprache: Liste) {list.remove (Sprache); }}} Ausnahme gemeldet, wenn das Programm ausgeführt wird:
Ausnahme in Thread "Haupt" java.util.concurrentModificationException
bei Java.util.ArrayList $ ittr.checkforcomodification (ArrayList.java:859)
bei Java.util.ArrayList $ ittr.Next (arrayList.java:831)
bei text.itaratOrst.main (itaratOstest.java:22)
Diese Ausnahme zeigt nur, dass die For-Each-Schleife Iterator verwendet, um die Sammlung zu iterieren, die auch Iterator.Next () nennt, die nach (Element) ändert und eine ConcurrentModificationException auswirkt.
Zusammenfassen:
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.