it-swarm-eu.dev

Wie funktioniert das Java 'für jede' Schleife?

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?

1414
Jay R.
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 .

1117
nsayer

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.

[Denis Bueno]

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.

473
Mikezx6r

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.

für jeden

_for(int i : intList) {
   System.out.println("An element in the list: " + i);
}
_

Iterator

_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 Unterschiede

Der 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: Leistung

Beim Zugriff auf Sammlungen ist foreachdeutlich 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.

Timing des Unterschieds zwischen Iterator- und Indexzugriff für primitive Int-Arrays

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.

Bei Auflistungen sind Iteratoren schneller als Indizes

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?

Die volle Testklasse

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;

/**
   &lt;P&gt;{@code Java TimeIteratorVsIndexIntArray 1000000}&lt;/P&gt;

   @see  &lt;CODE&gt;&lt;A HREF=&quot;https://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-Java&quot;&gt;https://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-Java&lt;/A&gt;&lt;/CODE&gt;
 **/
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

}
_
144
aliteralmind

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.

126
MRocklin

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);
}
37
toluju

In Java 8 Funktionen können Sie dies verwenden:

List<String> messages = Arrays.asList("First", "Second", "Third");

void forTest(){
    messages.forEach(System.out::println);
}

Ausgabe

First
Second
Third
23
Jrovalle

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.

23
EfForEffort

Wie in JLS für jede Schleife definiert, kann es zwei Formen geben:

  1. 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);
    }
    
  2. 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);
22
i_am_zero

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
22
PrivateName

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.

20
Ryan Delucchi

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.

15

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.

9
billjamesdev

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.

https://www.mkyong.com/Java8/Java-8-foreach-examples/

9
Dulith De Costa

Hier ist ein äquivalenter Ausdruck.

for(Iterator<String> sit = someList.iterator(); sit.hasNext(); ) {
    System.out.println(sit.next());
}
9
Hank

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);
});
8
vivekkurien

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).

7
Manohar

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 .

6
Pete

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 .

6
Girish Pandey

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.

5
L Joey
public static Boolean Add_Tag(int totalsize)
{ List<String> fullst = new ArrayList<String>();
            for(int k=0;k<totalsize;k++)
            {
              fullst.addAll();
            }
}
3

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

Quelle: Schleifen in Java - Ultimate Guide

3
gomisha

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.

2
WIll

Das sieht verrückt aus, aber es funktioniert

List<String> someList = new ArrayList<>(); //has content
someList.forEach(System.out::println);

Das funktioniert. Magic

1
Rei Brown