Erwägen:
List<String> someList = new ArrayList<String>();
// add "monkey", "donkey", "skeleton key" to someList
for (String item : someList) {
System.out.println(item);
}
Wie würde die äquivalente for
-Schleife aussehen, ohne die für jede -Syntax zu verwenden?
for (Iterator<String> i = someIterable.iterator(); i.hasNext();) {
String item = i.next();
System.out.println(item);
}
Beachten Sie, dass Sie das i.remove();
-Idiom nicht verwenden können, wenn Sie for ( : )
in Ihrer Schleife verwenden müssen oder auf irgendeine Weise auf den tatsächlichen Iterator zugreifen müssen, da der tatsächliche Iterator lediglich abgeleitet wird.
Wie Denis Bueno bemerkt hat, funktioniert dieser Code für jedes Objekt, das die Schnittstelle Iterable
implementiert.
Wenn die rechte Seite des for (:)
-Idioms ein array
und kein Iterable
-Objekt ist, verwendet der interne Code einen int-Indexzähler und prüft stattdessen mit array.length
. Siehe Java Language Specification .
Das Konstrukt für jedes gilt auch für Arrays. z.B.
String[] fruits = new String[] { "Orange", "Apple", "Pear", "Strawberry" };
for (String fruit : fruits) {
// fruit is an element of the `fruits` array.
}
das ist im Wesentlichen gleichwertig mit
for (int i = 0; i < fruits.length; i++) {
String fruit = fruits[i];
// fruit is an element of the `fruits` array.
}
Also, allgemeine Zusammenfassung:
[nsayer] Das Folgende ist die längere Form dessen, was passiert:
for(Iterator<String> i = someList.iterator(); i.hasNext(); ) { String item = i.next(); System.out.println(item); }
Beachten Sie, dass, wenn Sie i.remove () verwenden müssen; In Ihrer Schleife oder wenn Sie auf den tatsächlichen Iterator zugreifen, können Sie die for (:) - IDiom nicht verwenden, da der tatsächliche Iterator lediglich abgeleitet wird.
Dies wird durch die Antwort von nsayer impliziert, aber es ist erwähnenswert, dass die OPs für (..) -Syntax funktionieren, wenn "someList" Java.lang.Iterable implementiert - es muss keine Liste oder eine Sammlung von sein Java.util. Daher können auch Ihre eigenen Typen mit dieser Syntax verwendet werden.
Die in Java 5 hinzugefügte foreach
-Schleife (auch als "Enhanced for Loop" bezeichnet) entspricht der Verwendung eines Java.util.Iterator
- es ist syntaktischer Zucker für dasselbe. Daher sollte beim Lesen jedes Elements nacheinander ein foreach
immer einem Iterator vorgezogen werden, da dies praktischer und prägnanter ist.
_for(int i : intList) {
System.out.println("An element in the list: " + i);
}
_
_Iterator<Integer> intItr = intList.iterator();
while(intItr.hasNext()) {
System.out.println("An element in the list: " + intItr.next());
}
_
Es gibt Situationen, in denen Sie Iterator
direkt verwenden müssen. Wenn Sie beispielsweise versuchen, ein Element mit foreach
zu löschen, kann (wird?) Dies zu ConcurrentModificationException
führen.
foreach
vs. for
: Grundlegende UnterschiedeDer einzige praktische Unterschied zwischen for
und foreach
besteht darin, dass Sie bei indexierbaren Objekten keinen Zugriff auf den Index haben. Ein Beispiel, wenn die Basisschleife for
benötigt wird:
_for(int i = 0; i < array.length; i++) {
if(i < 5) {
// Do something special
} else {
// Do other stuff
}
}
_
Obwohl Sie mit foreach
manuell eine separate Index-Int-Variable erstellen könnten,
_int idx = -1;
for(int i : intArray) {
idx++;
...
}
_
dies wird nicht empfohlen, da Variablenbereich nicht ideal ist und die for
-Basisschleife einfach das Standardformat und das erwartete Format für diesen Anwendungsfall ist.
foreach
vs. for
: LeistungBeim Zugriff auf Sammlungen ist foreach
deutlich schneller als der Arrayzugriff der Basisschleife for
. Beim Zugriff auf Arrays ist der Zugriff über Indizes jedoch - zumindest bei primitiven Arrays und Wrapper-Arrays - erheblich schneller.
Indizes sind 23 - 40 Prozent schneller als Iteratoren beim Zugriff auf int
oder Integer
Arrays. Hier ist die Ausgabe der Testklasse am Ende dieses Beitrags, die die Zahlen in einem Primitiv-Int-Array mit 100 Elementen summiert (A ist Iterator, B ist Index):
_[C:\Java_code\]Java TimeIteratorVsIndexIntArray 1000000
Test A: 358,597,622 nanoseconds
Test B: 269,167,681 nanoseconds
B faster by 89,429,941 nanoseconds (24.438799231635727% faster)
[C:\Java_code\]Java TimeIteratorVsIndexIntArray 1000000
Test A: 377,461,823 nanoseconds
Test B: 278,694,271 nanoseconds
B faster by 98,767,552 nanoseconds (25.666236154695838% faster)
[C:\Java_code\]Java TimeIteratorVsIndexIntArray 1000000
Test A: 288,953,495 nanoseconds
Test B: 207,050,523 nanoseconds
B faster by 81,902,972 nanoseconds (27.844689860906513% faster)
[C:\Java_code\]Java TimeIteratorVsIndexIntArray 1000000
Test A: 375,373,765 nanoseconds
Test B: 283,813,875 nanoseconds
B faster by 91,559,890 nanoseconds (23.891659337194227% faster)
[C:\Java_code\]Java TimeIteratorVsIndexIntArray 1000000
Test A: 375,790,818 nanoseconds
Test B: 220,770,915 nanoseconds
B faster by 155,019,903 nanoseconds (40.75164734599769% faster)
[C:\Java_code\]Java TimeIteratorVsIndexIntArray 1000000
Test A: 326,373,762 nanoseconds
Test B: 202,555,566 nanoseconds
B faster by 123,818,196 nanoseconds (37.437545972215744% faster)
_
Ich habe dies auch für ein Integer
-Array ausgeführt, und Indizes sind immer noch der eindeutige Gewinner, aber nur zwischen 18 und 25 Prozent schneller.
Für ein List
von Integers
sind Iteratoren jedoch der eindeutige Gewinner. Ändern Sie einfach das Int-Array in der Testklasse in:
_List<Integer> intList = Arrays.asList(new Integer[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100});
_
Nehmen Sie die erforderlichen Änderungen an der Testfunktion vor (_int[]
_ bis _List<Integer>
_, length
bis size()
usw.):
_[C:\Java_code\]Java TimeIteratorVsIndexIntegerList 1000000
Test A: 3,429,929,976 nanoseconds
Test B: 5,262,782,488 nanoseconds
A faster by 1,832,852,512 nanoseconds (34.326681820485675% faster)
[C:\Java_code\]Java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,907,391,427 nanoseconds
Test B: 3,957,718,459 nanoseconds
A faster by 1,050,327,032 nanoseconds (26.038700083921256% faster)
[C:\Java_code\]Java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,566,004,688 nanoseconds
Test B: 4,221,746,521 nanoseconds
A faster by 1,655,741,833 nanoseconds (38.71935684115413% faster)
[C:\Java_code\]Java TimeIteratorVsIndexIntegerList 1000000
Test A: 2,770,945,276 nanoseconds
Test B: 3,829,077,158 nanoseconds
A faster by 1,058,131,882 nanoseconds (27.134122749113843% faster)
[C:\Java_code\]Java TimeIteratorVsIndexIntegerList 1000000
Test A: 3,467,474,055 nanoseconds
Test B: 5,183,149,104 nanoseconds
A faster by 1,715,675,049 nanoseconds (32.60101667104192% faster)
[C:\Java_code\]Java TimeIteratorVsIndexIntList 1000000
Test A: 3,439,983,933 nanoseconds
Test B: 3,509,530,312 nanoseconds
A faster by 69,546,379 nanoseconds (1.4816434912159906% faster)
[C:\Java_code\]Java TimeIteratorVsIndexIntList 1000000
Test A: 3,451,101,466 nanoseconds
Test B: 5,057,979,210 nanoseconds
A faster by 1,606,877,744 nanoseconds (31.269164666060377% faster)
_
In einem Test sind sie fast gleichwertig, aber bei Sammlungen gewinnt der Iterator.
* Dieser Beitrag basiert auf zwei Antworten, die ich auf Stack Overflow geschrieben habe:
Weitere Informationen: Was ist effizienter, eine for-each-Schleife oder ein Iterator?
Nach dem Lesen von diese Frage beim Stapelüberlauf habe ich diese Klasse zum Vergleichen der Zeit erstellt, die erforderlich ist, um zwei Dinge zu erledigen:
_import Java.text.NumberFormat;
import Java.util.Locale;
/**
<P>{@code Java TimeIteratorVsIndexIntArray 1000000}</P>
@see <CODE><A HREF="https://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-Java">https://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-Java</A></CODE>
**/
public class TimeIteratorVsIndexIntArray {
public static final NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
public static final void main(String[] tryCount_inParamIdx0) {
int testCount;
// Get try-count from a command-line parameter
try {
testCount = Integer.parseInt(tryCount_inParamIdx0[0]);
}
catch(ArrayIndexOutOfBoundsException | NumberFormatException x) {
throw new IllegalArgumentException("Missing or invalid command line parameter: The number of testCount for each test. " + x);
}
//Test proper...START
int[] intArray = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100};
long lStart = System.nanoTime();
for(int i = 0; i < testCount; i++) {
testIterator(intArray);
}
long lADuration = outputGetNanoDuration("A", lStart);
lStart = System.nanoTime();
for(int i = 0; i < testCount; i++) {
testFor(intArray);
}
long lBDuration = outputGetNanoDuration("B", lStart);
outputGetABTestNanoDifference(lADuration, lBDuration, "A", "B");
}
private static final void testIterator(int[] int_array) {
int total = 0;
for(int i = 0; i < int_array.length; i++) {
total += int_array[i];
}
}
private static final void testFor(int[] int_array) {
int total = 0;
for(int i : int_array) {
total += i;
}
}
//Test proper...END
//Timer testing utilities...START
public static final long outputGetNanoDuration(String s_testName, long l_nanoStart) {
long lDuration = System.nanoTime() - l_nanoStart;
System.out.println("Test " + s_testName + ": " + nf.format(lDuration) + " nanoseconds");
return lDuration;
}
public static final long outputGetABTestNanoDifference(long l_aDuration, long l_bDuration, String s_aTestName, String s_bTestName) {
long lDiff = -1;
double dPct = -1.0;
String sFaster = null;
if(l_aDuration > l_bDuration) {
lDiff = l_aDuration - l_bDuration;
dPct = 100.00 - (l_bDuration * 100.0 / l_aDuration + 0.5);
sFaster = "B";
}
else {
lDiff = l_bDuration - l_aDuration;
dPct = 100.00 - (l_aDuration * 100.0 / l_bDuration + 0.5);
sFaster = "A";
}
System.out.println(sFaster + " faster by " + nf.format(lDiff) + " nanoseconds (" + dPct + "% faster)");
return lDiff;
}
//Timer testing utilities...END
}
_
Hier ist eine Antwort, die keine Kenntnis von Java Iteratoren voraussetzt. Es ist weniger genau, aber es ist nützlich für die Bildung.
Während des Programmierens schreiben wir häufig Code, der wie folgt aussieht:
char[] grades = ....
for(int i = 0; i < grades.length; i++) { // for i goes from 0 to grades.length
System.out.print(grades[i]); // Print grades[i]
}
Mit der foreach-Syntax kann dieses allgemeine Muster natürlicher und syntaktisch weniger verrauscht geschrieben werden.
for(char grade : grades) { // foreach grade in grades
System.out.print(grade); // print that grade
}
Darüber hinaus gilt diese Syntax für Objekte wie Listen oder Mengen, die keine Array-Indizierung unterstützen, jedoch die Iterable-Schnittstelle Java implementieren.
Die for-each-Schleife in Java verwendet den zugrunde liegenden Iteratormechanismus. Es ist also identisch mit:
Iterator<String> iterator = someList.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
}
In Java 8 Funktionen können Sie dies verwenden:
List<String> messages = Arrays.asList("First", "Second", "Third");
void forTest(){
messages.forEach(System.out::println);
}
First
Second
Third
Es wird durch die Antwort von nsayer impliziert, aber es ist erwähnenswert, dass die OPs für (..) -Syntax funktionieren, wenn "someList" irgendetwas ist, das Java.lang.Iterable implementiert - es muss nicht sein eine Liste oder eine Sammlung aus Java.util. Daher können auch Ihre eigenen Typen mit dieser Syntax verwendet werden.
Wie in JLS für jede Schleife definiert, kann es zwei Formen geben:
Wenn der Ausdruckstyp ein Subtyp von Iterable
ist, lautet die Übersetzung wie folgt:
List<String> someList = new ArrayList<String>();
someList.add("Apple");
someList.add("Ball");
for (String item : someList) {
System.out.println(item);
}
// IS TRANSLATED TO:
for(Iterator<String> stringIterator = someList.iterator(); stringIterator.hasNext(); ) {
String item = stringIterator.next();
System.out.println(item);
}
Wenn der Ausdruck notwendigerweise einen Array-Typ T[]
hat, dann:
String[] someArray = new String[2];
someArray[0] = "Apple";
someArray[1] = "Ball";
for(String item2 : someArray) {
System.out.println(item2);
}
// IS TRANSLATED TO:
for (int i = 0; i < someArray.length; i++) {
String item2 = someArray[i];
System.out.println(item2);
}
Java 8 hat Streams eingeführt, die im Allgemeinen eine bessere Leistung erbringen. Wir können sie verwenden als:
someList.stream().forEach(System.out::println);
Arrays.stream(someArray).forEach(System.out::println);
Eine foreach-Schleifensyntax lautet:
for (type obj:array) {...}
Beispiel:
String[] s = {"Java", "Coffe", "Is", "Cool"};
for (String str:s /*s is the array*/) {
System.out.println(str);
}
Ausgabe:
Java
Coffe
Is
Cool
WARNUNG: Sie können mit der foreach-Schleife auf Array-Elemente zugreifen, diese jedoch NICHT initialisieren. Verwenden Sie dazu die ursprüngliche for
-Schleife.
WARNUNG: Sie müssen den Typ des Arrays mit dem anderen Objekt abgleichen.
for (double b:s) // Invalid-double is not String
Wenn Sie Elemente bearbeiten möchten, verwenden Sie die ursprüngliche for
-Schleife wie folgt:
for (int i = 0; i < s.length-1 /*-1 because of the 0 index */; i++) {
if (i==1) //1 because once again I say the 0 index
s[i]="2 is cool";
else
s[i] = "hello";
}
Wenn wir nun s auf die Konsole ausgeben, erhalten wir:
hello
2 is cool
hello
hello
Das Java "for-each" -Schleifenkonstrukt ermöglicht die Iteration über zwei Objekttypen:
T[]
(Arrays jeglicher Art)Java.lang.Iterable<T>
Die Schnittstelle Iterable<T>
hat nur eine Methode: Iterator<T> iterator()
. Dies funktioniert für Objekte vom Typ Collection<T>
, da die Collection<T>
-Schnittstelle Iterable<T>
erweitert.
Das in Wikipedia erwähnte Konzept einer foreach-Schleife wird nachfolgend hervorgehoben:
Im Gegensatz zu anderen for-Schleifenkonstrukten unterhalten foreach-Schleifen jedoch normalerweise keinen expliziten Zähler : Sie sagen im Wesentlichen "Tun Sie dies mit allem in dieser Menge" und nicht " mach das x mal ". Dies vermeidet potenzielle Fehler und macht das Lesen von Code einfacher.
Das Konzept einer foreach-Schleife beschreibt also, dass in der Schleife kein expliziter Zähler verwendet wird. Dies bedeutet, dass keine Indizes zum Durchlaufen der Liste erforderlich sind, sodass der Benutzer nicht durcheinander geraten kann. Um das allgemeine Konzept dieses einseitigen Fehlers zu beschreiben, nehmen wir ein Beispiel für eine Schleife, die mithilfe von Indizes in einer Liste durchlaufen wird.
// In this loop it is assumed that the list starts with index 0
for(int i=0; i<list.length; i++){
}
Angenommen, die Liste beginnt mit Index 1, dann löst diese Schleife eine Ausnahme aus, da bei Index 0 kein Element gefunden wird und dieser Fehler als Fehler nach dem anderen bezeichnet wird. Um diesen Fehler zu vermeiden, wird das Konzept einer foreach-Schleife verwendet. Es mag auch andere Vorteile geben, aber ich denke, dies ist das Hauptkonzept und der Hauptvorteil der Verwendung einer foreach-Schleife.
Beachten Sie auch, dass die Verwendung der "foreach" -Methode in der ursprünglichen Frage einige Einschränkungen aufweist, z. B., dass Elemente während der Iteration nicht aus der Liste entfernt werden können.
Die neue for-Schleife ist einfacher zu lesen und macht einen separaten Iterator überflüssig. Sie kann jedoch nur in schreibgeschützten Iterationsdurchläufen verwendet werden.
Mit älteren Java Versionen einschließlich Java 7
können Sie die foreach
Schleife wie folgt verwenden.
List<String> items = new ArrayList<>();
items.add("A");
items.add("B");
items.add("C");
items.add("D");
items.add("E");
for(String item : items){
System.out.println(item);
}
Das Folgende ist die neueste Möglichkeit, die foreach
-Schleife in Java 8
zu verwenden.
(Schleife eine Liste mit forEach
+ Lambda-Ausdruck oder Methodenreferenz)
//lambda
//Output : A,B,C,D,E
items.forEach(item->System.out.println(item));
//method reference
//Output : A,B,C,D,E
items.forEach(System.out::println);
Weitere Informationen finden Sie unter diesem Link.
Hier ist ein äquivalenter Ausdruck.
for(Iterator<String> sit = someList.iterator(); sit.hasNext(); ) {
System.out.println(sit.next());
}
Eine Alternative zu forEach, um Ihr "für jeden" zu vermeiden:
List<String> someList = new ArrayList<String>();
Variante 1 (uni):
someList.stream().forEach(listItem -> {
System.out.println(listItem);
});
Variante 2 (parallele Ausführung (schneller)):
someList.parallelStream().forEach(listItem -> {
System.out.println(listItem);
});
In Java 8 stellten sie forEach vor. Über die Liste können Maps geloopt werden.
Schleife eine Liste mit für jede
List<String> someList = new ArrayList<String>();
someList.add("A");
someList.add("B");
someList.add("C");
someList.forEach(listItem -> System.out.println(listItem))
oder
someList.forEach(listItem-> {
System.out.println(listItem);
});
Schleife eine Karte mit für jede
Map<String, String> mapList = new HashMap<>();
mapList.put("Key1", "Value1");
mapList.put("Key2", "Value2");
mapList.put("Key3", "Value3");
mapList.forEach((key,value)->System.out.println("Key: " + key + " Value : " + value));
oder
mapList.forEach((key,value)->{
System.out.println("Key : " + key + " Value : " + value);
});
Es fügt Ihrem Code Schönheit hinzu, indem es alle grundlegenden Unordnung von Schleifen entfernt. Es gibt Ihrem Code ein sauberes Aussehen, wie unten angegeben.
normale for
Schleife:
void cancelAll(Collection<TimerTask> list) {
for (Iterator<TimerTask> i = list.iterator(); i.hasNext();)
i.next().cancel();
}
Verwenden von for-each:
void cancelAll(Collection<TimerTask> list) {
for (TimerTask t : list)
t.cancel();
}
for-each ist ein Konstrukt über einer Sammlung, das Iterator implementiert. Denken Sie daran, dass Ihre Sammlung Iterator implementieren sollte. Andernfalls können Sie es nicht mit for-each verwenden.
Die folgende Zeile lautet " für jede TimerTask t in der Liste. "
for (TimerTask t : list)
Es gibt weniger Chancen für Fehler im Falle von für jeden. Sie müssen sich nicht darum kümmern, den Iterator zu initialisieren oder den Schleifenzähler zu initialisieren und zu beenden (wo Fehler auftreten können).
Es würde ungefähr so aussehen. Sehr crufty.
for (Iterator<String> i = someList.iterator(); i.hasNext(); )
System.out.println(i.next());
Es gibt eine gute Beschreibung von für jedes in der Sun-Dokumentation .
Vor Java 8 müssen Sie Folgendes verwenden:
Iterator<String> iterator = someList.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
}
Mit der Einführung von Streams in Java 8 können Sie jedoch das Gleiche in viel weniger Syntax tun. Zum Beispiel können Sie für Ihr someList
Folgendes tun:
someList.stream().forEach(System.out::println);
Weitere Informationen zu Streams finden Sie hier .
Wie so viele gute Antworten sagten, muss ein Objekt den Iterable interface
implementieren, wenn es eine for-each
-Schleife verwenden möchte.
Ich werde ein einfaches Beispiel posten und versuchen, auf andere Weise zu erklären, wie eine for-each
-Schleife funktioniert.
Beispiel für die for-each
-Schleife:
public class ForEachTest {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("111");
list.add("222");
for (String str : list) {
System.out.println(str);
}
}
}
Wenn wir dann javap
verwenden, um diese Klasse zu dekompilieren, erhalten wir das folgende Bytecode-Beispiel:
public static void main(Java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=4, args_size=1
0: new #16 // class Java/util/ArrayList
3: dup
4: invokespecial #18 // Method Java/util/ArrayList."<init>":()V
7: astore_1
8: aload_1
9: ldc #19 // String 111
11: invokeinterface #21, 2 // InterfaceMethod Java/util/List.add:(Ljava/lang/Object;)Z
16: pop
17: aload_1
18: ldc #27 // String 222
20: invokeinterface #21, 2 // InterfaceMethod Java/util/List.add:(Ljava/lang/Object;)Z
25: pop
26: aload_1
27: invokeinterface #29, 1 // InterfaceMethod Java/util/List.iterator:()Ljava/util/Iterator;
Wie aus der letzten Zeile des Beispiels hervorgeht, konvertiert der Compiler die Verwendung des Schlüsselworts for-each
zur Kompilierungszeit automatisch in die Verwendung eines Iterator
. Dies erklärt möglicherweise, warum ein Objekt, das den Iterable interface
nicht implementiert, einen Exception
auslöst, wenn es versucht, die for-each
-Schleife zu verwenden.
public static Boolean Add_Tag(int totalsize)
{ List<String> fullst = new ArrayList<String>();
for(int k=0;k<totalsize;k++)
{
fullst.addAll();
}
}
Das Java für jede Schleife (auch erweitert für Schleife) ist eine vereinfachte Version einer for-Schleife. Der Vorteil ist, dass weniger Code geschrieben und weniger Variablen verwaltet werden müssen. Der Nachteil ist, dass Sie keine Kontrolle über den Schrittwert und keinen Zugriff auf den Schleifenindex innerhalb des Schleifenkörpers haben.
Sie werden am besten verwendet, wenn der Schrittwert ein einfaches Inkrement von 1 ist und Sie nur Zugriff auf das aktuelle Schleifenelement benötigen. Zum Beispiel, wenn Sie jedes Element in einem Array oder einer Sammlung durchlaufen müssen, ohne vor oder hinter das aktuelle Element zu schauen.
Es gibt keine Schleifeninitialisierung, keine Boolesche Bedingung und der Schrittwert ist implizit und ein einfaches Inkrement. Dies ist der Grund, warum sie für Schleifen als viel einfacher als normal angesehen werden.
Enhanced for-Schleifen folgen dieser Ausführungsreihenfolge:
1) Schleifenkörper
2) Wiederholen Sie den Vorgang ab Schritt 1, bis das gesamte Array oder die gesamte Sammlung durchlaufen wurde
Beispiel - Integer Array
int [] intArray = {1, 3, 5, 7, 9};
for(int currentValue : intArray) {
System.out.println(currentValue);
}
Die Variable currentValue enthält den aktuellen Wert, der im Array intArray durchlaufen wird. Beachten Sie, dass es keinen expliziten Schrittwert gibt - er wird immer um 1 erhöht.
Man kann sich vorstellen, dass der Doppelpunkt „in“ bedeutet. Die erweiterte for-Schleifendeklaration lautet also: Schleife über intArray und speichere den aktuellen Array-Int-Wert in der Variable currentValue.
Ausgabe:
1
3
5
7
9
Beispiel - String Array
Wir können die for-each-Schleife verwenden, um ein Array von Zeichenfolgen zu durchlaufen. Die Schleifendeklaration besagt: Schleife über das Array myStrings String und speichere den aktuellen String-Wert in der Variablen currentString.
String [] myStrings = {
"alpha",
"beta",
"gamma",
"delta"
};
for(String currentString : myStrings) {
System.out.println(currentString);
}
Ausgabe:
alpha
beta
gamma
delta
Beispiel - Liste
Die erweiterte for-Schleife kann auch verwendet werden, um eine Java.util.List wie folgt zu durchlaufen:
List<String> myList = new ArrayList<String>();
myList.add("alpha");
myList.add("beta");
myList.add("gamma");
myList.add("delta");
for(String currentItem : myList) {
System.out.println(currentItem);
}
Die Schleifendeklaration besagt: Schleife über myList List of Strings und speichere den aktuellen Listenwert in der Variablen currentItem.
Ausgabe:
alpha
beta
gamma
delta
Beispiel - Set
Die erweiterte for-Schleife kann auch zum Durchlaufen einer Java.util.Set wie folgt verwendet werden:
Set<String> mySet = new HashSet<String>();
mySet.add("alpha");
mySet.add("alpha");
mySet.add("beta");
mySet.add("gamma");
mySet.add("gamma");
mySet.add("delta");
for(String currentItem : mySet) {
System.out.println(currentItem);
}
Die Schleifendeklaration besagt: Schleife über mySet Set of Strings und speichere den aktuellen Set-Wert in der Variablen currentItem. Da dies ein Set ist, werden keine doppelten String-Werte gespeichert.
Ausgabe:
alpha
delta
beta
gamma
Das Java für jedes Idiom kann nur auf Arrays oder Objekte vom Typ * Iterable angewendet werden. Dieses Idiom ist implizit , da es wirklich von einem Iterator unterstützt wird. Der Iterator wird vom Programmierer programmiert und verwendet häufig einen Ganzzahlindex oder einen Knoten (abhängig von der Datenstruktur), um seine Position zu verfolgen. Auf dem Papier ist es langsamer als eine reguläre for-Schleife, am wenigsten für "lineare" Strukturen wie Arrays und Listen, bietet aber eine größere Abstraktion.
Das sieht verrückt aus, aber es funktioniert
List<String> someList = new ArrayList<>(); //has content
someList.forEach(System.out::println);
Das funktioniert. Magic