Wie funktioniert die erweiterte for-Anweisung für Arrays und wie erhält man einen Iterator für ein Array?
Angesichts des folgenden code-snippet:
int[] arr = {1, 2, 3};
for (int i : arr)
System.out.println(i);
Habe ich folgende Fragen:
- Wie wirkt sich die oben for-each-Schleife arbeiten?
- Wie bekomme ich einen iterator für ein array in Java?
- Ist das array konvertiert, um eine Liste zu bekommen die iterator?
InformationsquelleAutor der Frage Emil | 2010-10-12
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie möchten, eine
Iterator
über einem array, kann natürlich eine direkte Implementierungen gibt, anstatt zu Verpacken das array in einList
. Zum Beispiel:Apache-Commons-Collections
ArrayIterator
Oder dieser, wenn Sie möchten, dass Generika verwendet werden:
com.Ostermiller.util.ArrayIterator
Beachten Sie, dass, wenn Sie wollen, um eine
Iterator
über primitiven Typen können Sie nicht, weil eine primitive Typ kann nicht sein, die einen generischen parameter. E. g., wenn Sie möchten, eineIterator<int>
haben, müssen Sie auf eineIterator<Integer>
statt, deren Ergebnis eine Menge von autoboxing und -unboxing wenn es das ist, unterstützt durch eineint[]
.InformationsquelleAutor der Antwort uckelman
Nein, es ist keine Konvertierung. Die JVM nur iteriert über das array mit einem index in den hintergrund.
Zitat von Effektiven Java 2nd Ed., Item 46:
So dass Sie nicht bekommen kann eine
Iterator
für ein array (es sei denn natürlich durch Umwandlung in eineList
ersten).InformationsquelleAutor der Antwort Péter Török
Arrays.asList(arr).iterator();Oder schreiben Sie Ihre eigenen, Implementierung ListIterator-interface..
InformationsquelleAutor der Antwort Jochem
Google Guave Libraries collection stellt eine solche Funktion:
Sollte man prefere Guave über die Apache-Sammlung (die scheint verlassen zu werden).
InformationsquelleAutor der Antwort 30thh
In Java 8:
InformationsquelleAutor der Antwort Haneu
InformationsquelleAutor der Antwort Ashok Domadiya
Streng genommen, können Sie nicht bekommen einen iterator, der die primitiven array, weil Iterator.die next () - kann nur ein Objekt zurückgeben. Aber durch die Magie des autoboxing, können Sie den iterator mit dem Arrays.asList() - Methode.Die obige Antwort ist falsch, Sie können nicht
Arrays.asList()
auf einem primitiven array, würde es wieder einList<int[]>
. Verwenden Guave'sInts.asList()
statt.InformationsquelleAutor der Antwort Sean Patrick Floyd
Kann man nicht direkt einen iterator für ein array.
Aber können Sie eine Liste verwenden, unterstützt durch das array, und Sie bekommen einen ierator auf dieser Liste. Für das array muss eine Integer array (anstelle eines int-array):
Hinweis: es ist nur Theorie. Sie können einen iterator wie diese, aber ich Sie davon abhalten, das zu tun. Leistungen sind nicht gut im Vergleich zu einer direkten iteration über das array mit der "erweiterten syntax".
Hinweis 2: eine Liste zu konstruieren, die mit dieser Methode nicht alle Methoden (da die Liste wird unterstützt durch die Arrays, die eine Feste Größe haben). Zum Beispiel, "remove" - Methode des iterator wird zu einer Ausnahme führen.
InformationsquelleAutor der Antwort Benoit Courtine
Wie wirkt sich die oben for-each-Schleife arbeiten?
Wie viele andere array-Funktionen, die JSL erwähnt arrays explizit und gibt Ihnen Magische Eigenschaften. JLS 7 14.14.2:
Ist das array konvertiert, um eine Liste zu bekommen die iterator?
Let ' s
javap
:dann:
main
Methode mit ein wenig Bearbeiten, um es einfacher zu Lesen ist:Aufteilung:
0
zu14
: erstellen Sie das array15
zu22
: bereiten Sie sich für die for-Schleife. Bei 22store integer0
vom stack in die lokale position4
. Das ist die loop variable.24
zu47
: die Schleife. Die loop-variable abgerufen am31
und erhöht bei44
. Wenn es gleich der array-Länge, die ist gespeichert in der lokalen variable 3 auf die Kontrolle an27
wird die Schleife beendet.Abschluss: es ist dasselbe wie eine explizite for-Schleife mit index-variable, keine itereators beteiligt.
InformationsquelleAutor der Antwort Ciro Santilli 新疆改造中心 六四事件 法轮功
For (2), Guave bietet genau das, was Sie wollen, wie Int.asList(). Es ist ein äquivalent für jeden primitiven Typ in der zugehörigen Klasse, z.B.
Booleans
fürboolean
usw.InformationsquelleAutor der Antwort BeeOnRope
Ich bin ein bisschen spät, um das Spiel, aber ich bemerkte, dass einige wichtige Punkte ausgelassen wurden, insbesondere in Bezug auf Java 8 und die Effizienz der
Arrays.asList
.1. Wie funktioniert die for-each-Schleife arbeiten?
Als Ciro Santilli 六四事件 法轮功 包卓轩 wies darauf hin, es ist ein handliches Dienstprogramm für die Prüfung der bytecode, der im Lieferumfang des JDK:
javap
. Mit, dass, können wir feststellen, dass die beiden folgenden code-snippets zu produzieren identischen bytecode wie Java 8u74:For-each-Schleife:
For-Schleife:
2. Wie bekomme ich einen iterator für ein array in Java?
Während dies funktioniert nicht für primitive, es sollte angemerkt werden, dass die Umwandlung von einem array in eine Liste mit
Arrays.asList
hat keine Auswirkungen auf die Leistung in entscheidender Weise. Die Auswirkungen auf die beiden Speicher und die Leistung ist fast unermesslich.Arrays.asList
nicht mit einem normalen Liste-Implementierung, die leicht zugänglich ist, wie eine Klasse. Es nutztjava.util.Arrays.ArrayList
das ist nicht das gleiche wiejava.util.ArrayList
. Es ist ein sehr dünner wrapper um ein array und kann nicht geändert werden. Blick auf den source-code fürjava.util.Arrays.ArrayList
können wir sehen, dass es ist entworfen, um funktionell äquivalent zu einem array. Es ist fast kein Aufwand. Beachten Sie, dass ich ausgelassen habe, alle, aber die meisten relevanten code und fügte meine eigenen Kommentare.Wird der iterator auf
java.util.AbstractList.Itr
. Soweit Iteratoren gehen, es ist sehr einfach; man ruft einfachget()
bissize()
erreicht ist, ähnlich wie eine Anleitung für die Schleife tun würde. Es ist die einfachste und am meisten in der Regel effiziente Umsetzung einerIterator
für ein array.Wieder
Arrays.asList
keinenjava.util.ArrayList
. Es ist viel mehr leicht und eignet sich für den Erhalt ein iterator mit vernachlässigbarer Aufwand.Primitive arrays
Als andere haben darauf hingewiesen,
Arrays.asList
können nicht verwendet werden, die auf primitive arrays. Java 8 bringt einige neue Technologien für den Umgang mit Sammlungen von Daten, von denen einige könnte verwendet werden, um zu extrahieren einfachen und relativ effizienten Iteratoren von arrays. Beachten Sie, dass wenn Sie, dass Generika verwendet werden, sind Sie immer gehen, um die Boxen-unboxing problem: Sie benötigen zum konvertieren von int nach Integer und dann wieder auf int. Während boxing/unboxing ist in der Regel vernachlässigbar ist, hat es eine O(1) Auswirkungen auf die Leistung in diesem Fall und könnte zu Problemen mit sehr großen arrays oder auf einem Computer mit sehr begrenzten Ressourcen (D. H., SoC).Mein persönlicher Favorit für jede Art von array casting/boxing-operation in Java 8 ist die neue stream-API. Zum Beispiel:
Die streams-API bietet auch Konstrukte für die Vermeidung der Boxen-Problem in den ersten Platz, aber dies erfordert Verzicht auf Iteratoren zu Gunsten von streams. Es gibt engagierte stream-Typen für int, long und double (IntStream, LongStream, und DoubleStream, beziehungsweise).
Interessanterweise Java 8 fügt auch
java.util.PrimitiveIterator
. Dies bietet das beste aus beiden Welten: die Kompatibilität mitIterator<T>
über Boxen zusammen mit Methoden, um zu vermeiden Boxen. PrimitiveIterator hat drei eingebaute Schnittstellen, die Sie erweitern: OfInt, OfLong, und OfDouble. Alle drei Kontrollkästchen, wennnext()
genannt wird, sondern können sich auch wieder über primitive Methoden wienextInt()
. Neuer code, der entwickelt wurde für die Java 8 sollte vermeiden, mitnext()
es sei denn Boxen ist absolut notwendig.Wenn Sie noch nicht auf Java 8, leider, Ihre einfachste option ist viel weniger prägnant und ist fast sicher gehen zu beteiligen Boxen:
Oder wenn Sie wollen, etwas zu schaffen, das mehr wiederverwendbar:
Können Sie rund um die Boxen-Problem hier, indem Sie Ihre eigenen Methoden für den Erhalt der primitiven, aber es würde funktionieren nur mit Ihren eigenen internen code.
3. Ist das array konvertiert, um eine Liste zu bekommen die iterator?
Nein, es ist nicht. Jedoch, das bedeutet nicht, wickeln Sie es in einer Liste wird Ihnen schlechter Leistung, wenn du etwas leichtes wie
Arrays.asList
.InformationsquelleAutor der Antwort Zenexer
Ich bin einer der jüngsten Studenten, aber ich GLAUBE, das original-Beispiel mit int[] wird die Iteration über die primitive-array, aber nicht mit einem Iterator-Objekt. Es bloß hat die gleiche (ähnliche) syntax mit verschiedenen Inhalten,
Arrays.asList() ANSCHEINEND nur gilt Liste von Methoden auf ein Objekt-array, das es gegeben - aber auch für jede andere Art von Objekt, auch ein primitives array, iterator().next() ANSCHEINEND nur Hände, die Sie die Referenz auf das ursprüngliche Objekt, behandeln Sie es als eine Liste mit einem element. Können wir sehen, source-code für diese? Würden Sie nicht lieber eine Ausnahme? Nie Verstand. Ich denke (VERMUTE), dass es wie (oder es IST) ein singleton-Sammlung. So, hier asList() unerheblich ist der Fall mit einem primitiven array, aber verwirrend. Ich WEIß nicht, ich bin im Recht, aber ich schrieb ein Programm, das sagt, dass ich bin.
Also in diesem Beispiel (wobei im Grunde asList() nicht das tut, was Sie dachte, es würde, und ist daher nicht etwas, das man tatsächlich nutzen diese Möglichkeit) - ich hoffe, der code funktioniert besser als meine-Kennzeichnung-als-code, und, hey, schaut die Letzte Zeile:
InformationsquelleAutor der Antwort Robert Carnegie
Ich mag die Antwort von 30thh mit
Iterators
aus Guave. Jedoch, von einigen frameworks bekomme ich null statt einem leeren array, undIterators.forArray(array)
behandelt nicht gut. Also ich kam mit dieser Helfer-Methode, die Sie aufrufen können, mitIterator<String> it = emptyIfNull(array);
InformationsquelleAutor der Antwort Max Hohenegger