1729 Stimmen

Wie funktioniert die Java-'for each'-Schleife?

Bedenken Sie:

List<String> someList = new ArrayList<String>();
// add "monkey", "donkey", "skeleton key" to someList

for (String item : someList) {
    System.out.println(item);
}

Was wäre das Äquivalent for Schleife aussehen, ohne die Verwendung der für jede Syntax?

9voto

L Joey Punkte 135

Wie so viele gute Antworten sagten, muss ein Objekt die Iterable interface wenn es eine for-each Schleife.

Ich werde ein einfaches Beispiel anführen und versuchen, auf eine andere Art und Weise zu erklären, wie eine for-each Schleife funktioniert.

Le site for-each Beispiel einer 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);
        }
    }
}

Dann, wenn wir javap um diese Klasse zu dekompilieren, erhalten wir dieses 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 wir in der letzten Zeile des Beispiels sehen können, konvertiert der Compiler automatisch die Verwendung von for-each Schlüsselwort auf die Verwendung eines Iterator zur Kompilierzeit. Das könnte erklären, warum object, das nicht die Iterable interface wird ein Exception wenn es versucht, die for-each Schleife.

9voto

mightyWOZ Punkte 6908

Wie in vielen anderen Antworten richtig festgestellt wird, ist die for each loop ist nur syntaktischer Zucker für das gleiche alte for loop und der Compiler übersetzt sie in dieselbe alte for-Schleife.

javac (open jdk) hat einen Schalter -XD-printflat , die eine Java-Datei erzeugt, aus der alle syntaktischen Fehler entfernt wurden. Der vollständige Befehl sieht wie folgt aus

javac -XD-printflat -d src/ MyFile.java

//-d is used to specify the directory for output java file

Entfernen wir also den syntaktischen Zucker

Um diese Frage zu beantworten, habe ich eine Datei erstellt und zwei Versionen von for each einer mit array und eine weitere mit einer list . mein java Datei sah wie folgt aus.

import java.util.*;
public class Temp{

    private static void forEachArray(){
        int[] arr = new int[]{1,2,3,4,5};
        for(int i: arr){
            System.out.print(i);
        }
    }

    private static void forEachList(){
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        for(Integer i: list){
            System.out.print(i);
        }
    }
}

Wenn ich compiled diese Datei mit dem obigen Schalter, erhielt ich die folgende Ausgabe.

import java.util.*;

public class Temp {

    public Temp() {
        super();
    }

    private static void forEachArray() {
        int[] arr = new int[]{1, 2, 3, 4, 5};
        for (/*synthetic*/ int[] arr$ = arr, len$ = arr$.length, i$ = 0; i$ < len$; ++i$) {
            int i = arr$[i$];
            {
                System.out.print(i);
            }
        }
    }

    private static void forEachList() {
        List list = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4), Integer.valueOf(5)});
        for (/*synthetic*/ Iterator i$ = list.iterator(); i$.hasNext(); ) {
            Integer i = (Integer)i$.next();
            {
                System.out.print(i);
            }
        }
    }
}

Sie können sehen, dass zusammen mit den anderen syntaktischen Zucker (Autoboxing) für jede Schleifen wurde zu einfachen Schleifen geändert.

8voto

gomisha Punkte 2065

Le site Java for each-Schleife (auch bekannt als erweiterte for-Schleife) ist eine vereinfachte Version einer for-Schleife. Der Vorteil ist, dass weniger Code geschrieben werden muss und weniger Variablen zu verwalten sind. 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 eine einfache Erhöhung um 1 ist und wenn Sie nur Zugriff auf das aktuelle Schleifenelement benötigen. Zum Beispiel, wenn Sie eine Schleife über jedes Element in einem Array oder einer Sammlung machen 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. Aus diesem Grund werden sie als viel einfacher angesehen als normale for-Schleifen.

Erweiterte for-Schleifen folgen dieser Reihenfolge der Ausführung:

1) Schlaufenkörper

2) Wiederholung von 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, über den im Array intArray geschleift wird. Beachten Sie, dass es keinen expliziten Schrittwert gibt - es handelt sich immer um eine Erhöhung um 1.

Der Doppelpunkt kann als "in" verstanden werden. Die erweiterte for-Schleifendeklaration besagt also: Schleife über intArray und Speichern des aktuellen int-Wertes des Arrays in die Variable currentValue.

出力します。

1
3
5
7
9

Beispiel - String-Array

Wir können die for-each-Schleife verwenden, um über ein Array von Zeichenketten zu iterieren. Die Schleifendeklaration lautet: Schleife über myStrings String-Array und Speichern des aktuellen String-Werts in die Variable currentString.

String [] myStrings  = {
  "alpha",
  "beta",
  "gamma",
  "delta"
};

for(String currentString : myStrings) {
  System.out.println(currentString);
}

出力します。

alpha
beta
gamma
delta

Beispiel - Liste

Die erweiterte for-Schleife kann auch zur Iteration über eine java.util.List wie folgt verwendet werden:

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 Liste von Strings und Speichern des aktuellen Listenwertes in die Variable currentItem.

出力します。

alpha
beta
gamma
delta

Beispiel - Setzen

Die erweiterte for-Schleife kann auch zur Iteration über ein 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 lautet: Schleife über mySet Set of Strings und Speichern des aktuellen Set-Wertes in die Variable currentItem. Da es sich um ein Set handelt, werden doppelte String-Werte nicht gespeichert.

出力します。

alpha
delta
beta
gamma

Quelle: Schleifen in Java - Ultimativer Leitfaden

6voto

Santhosh Rajkumar Punkte 111
public static Boolean Add_Tag(int totalsize)
{ List<String> fullst = new ArrayList<String>();
            for(int k=0;k<totalsize;k++)
            {
              fullst.addAll();
            }
}

0 Stimmen

Ich glaube nicht, dass wir diese Antwort brauchen. Siehe dieser Kommentar .

5voto

TheArchon Punkte 303

Das Java for-each Idiom kann nur auf Arrays oder Objekte des Typs *Iterabel . Diese Redewendung ist implizit da sie wirklich durch einen Iterator unterstützt wird. Der Iterator wird vom Programmierer programmiert und verwendet oft einen Integer-Index oder einen Knoten (je nach Datenstruktur), um seine Position zu verfolgen. Auf dem Papier ist er langsamer als eine normale for-Schleife, zumindest für "lineare" Strukturen wie Arrays und Listen, aber er bietet eine größere Abstraktion.

0 Stimmen

-1: das ist (im Allgemeinen) viel weniger lesbar: sogar Ihr eigenes Beispiel (das erste) ist falsch, da es das erste Element im Array auslässt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X