Foreach vs gemeinsame Schleife

7

Ich habe gerade angefangen, Java zu lernen, und das erste, was mir dabei auffiel, ist die foreach -Schleife. Ich weiß nicht, wie es funktioniert, das erste, was ich gemacht habe, war:

%Vor%

Und offensichtlich konnte 1 keinem Element des Arrays zugewiesen werden. Dann fügte ich System.out.print(i); (nach i = 1; ) dem Hauptteil der Schleife hinzu und sah, dass die Ausgabe des Bildschirms 1111111111 war, aber da etwas mit i innerhalb der Schleife gemacht wurde, ist höchstwahrscheinlich i gültig eine Kopie von jedem Element des Arrays, oder? (erste Fragen)

Wenn das Obige wahr ist, heißt das nicht, dass die foreach -Schleife viel langsamer ist als die gewöhnliche for-Schleife, da es Kopien jedes Elements des Arrays erzeugt? Oder da Java keine Pointer und Zeigerarithmetik hat, kann oprator[] in einer anderen "schlechten" Weise entworfen werden, dass das Kopieren jedes Elements tatsächlich schneller ist?

Und wenn die obigen Annahmen richtig sind, warum würde man eine offensichtlich langsamere foreach -Schleife anstelle einer gewöhnlichen for -Schleife verwenden?

Kurz gesagt, die Fragen:

  • Ist i die Kopie jedes Elements von array ? Wenn nicht, was ist es? dann?

  • Ist die foreach -Schleife nicht langsamer als die normale? Wenn nicht, wie "schlecht" ist dann operator[] designed?

  • Es gibt nichts außer Lesbarkeit in einer foreach Schleife zu gewinnen?

Alexandru Barbarosie 13.09.2013, 14:02
quelle

4 Antworten

11

Im Code

%Vor%

Sie deklarieren eine Variable i , die bei jeder Schleifeniteration den Wert des nächsten Elements im Array erhält, es ist kein Verweis auf dieses Element.

In

%Vor%

Sie weisen der Variablen einen neuen Wert zu, nicht dem Element im Array.

Sie können die Werte von Array-Elementen nicht direkt mit einer foreach-Schleife festlegen. Verwenden Sie dafür eine normale for -Schleife

%Vor%

Im obigen Beispiel verwenden Sie die deklarierte Variable i als Index für das Element im Array.

%Vor%

greift auf das Element selbst zu, dessen Wert Sie ändern können.

  

Natürlich konnte Ans kein Element des Arrays zuordnen. Das i   hinzugefügt System.out.print (i); an den Körper der Schleife und sah, dass die   Ausgabe des Bildschirms war 1111111111, aber seit etwas mit i getan   Innerhalb der Schleife gilt, dass ich höchstwahrscheinlich eine Kopie jedes Elements bin   von der Anordnung, nicht wahr? (erste Fragen)

Sie müssen System.out.print(i) nach i = 1 setzen, sonst erhalten Sie 0000000 .

  

Wenn das Obige wahr ist, heißt das nicht, dass die foreach-Schleife viel ist   langsamer als die übliche for-Schleife, da es sich um das Erstellen von Kopien handelt   Jedes Element des Arrays? Oder seit Java keine Zeiger und hat   Zeigerarithmetik kann der Oporator [] in einigen anderen entworfen werden   "schlecht" Mode, dass das Kopieren jedes Element ist eigentlich schneller?

Sehen Sie sich hier an wie funktioniert die foreach-Schleife? Für Arrays

%Vor%

entspricht

%Vor%

Also ist es nicht langsamer. Du machst eine primitive Schöpfung auf dem Stapel.

Es hängt von der Implementierung ab. Für Arrays ist es in keiner Weise langsamer. Es dient nur verschiedenen Zwecken.

  

warum würde man eine offensichtlich langsamere foreach-Schleife anstelle einer gewöhnlichen verwenden   Forloop?

Ein Grund ist die Lesbarkeit. Ein anderes ist, wenn Sie nicht die Elementreferenzen des Arrays ändern möchten, sondern die aktuellen Referenzen.

Nehmen Sie ein Referenztypbeispiel

%Vor%

Bei primitiven Typen funktioniert so etwas nicht.

%Vor%     
Sotirios Delimanolis 13.09.2013 14:04
quelle
6

Aus Element 46 in Effective Java von Joshua Bloch:

  

Die for-each-Schleife, die in Release 1.5 eingeführt wurde, beseitigt das Durcheinander   und die Möglichkeit eines Fehlers durch Verbergen des Iterators oder der Indexvariablen   vollständig. Das resultierende Idiom gilt gleichermaßen für Sammlungen und   Arrays:

%Vor%      

Wenn Sie den Doppelpunkt (:) sehen, lesen Sie ihn als "in". So, die Schleife oben   liest als "für jedes Element e in Elementen." Beachten Sie, dass es keine gibt   Leistungseinbußen für die Verwendung der for-each-Schleife, auch für Arrays. Im   Tatsächlich kann es einen leichten Leistungsvorteil gegenüber einem gewöhnlichen anbieten   Schleife in einigen Fällen, da es das Limit des Arrays berechnet   Index nur einmal. Während Sie dies von Hand (Punkt 45) tun können, Programmierer   mach das nicht immer.

Vorteile

  
  1. Lesbarkeit
  2.   
  3. Es erhöht das Abstraktionsniveau - anstatt die Details auf niedriger Ebene auszudrücken, wie man eine Liste umläuft   oder Array (mit einem Index oder Iterator), sagt der Entwickler das einfach   sie wollen Schleife und die Sprache kümmert sich um den Rest.
  4.   

Nachteil:

  

Sie können nicht auf den Index zugreifen oder ein Element entfernen.

Zusammenfassend

  

die erweiterten for-loop-Angebote

     
  1. Eine knappe Syntax auf höherer Ebene, um eine Liste oder ein Array zu durchlaufen, die

         

    1.1 verbessert die Klarheit

         

    1.2 Lesbarkeit.

         

    Es fehlt jedoch: Sie können auf die Indexschleife zugreifen oder ein Element entfernen.

  2.   
    
JNL 13.09.2013 14:36
quelle
3

Das Festlegen der Werte nach Referenz funktionierte nicht, da int ein primitiver Typ ist. Für jede Art von Objekt [] würde es funktionieren. Das Erstellen einer Kopie eines primitiven Typs ist sehr schnell und wird vom Prozessor viele Male durchgeführt, ohne dass Sie es merken.

Die foreach -Schleife ist besser lesbar, aber auch schreibbarer. Ein häufiger Programmierfehler ist:

%Vor%

Es ist unmöglich, diesen Fehler mit einer foreach Schleife zu machen.

    
MikeFHay 13.09.2013 14:14
quelle
2
  

Die for-Anweisung hat auch eine andere Form, die für die Iteration durch Collections und Arrays entworfen wurde. Diese Form wird manchmal als die erweiterte for-Anweisung bezeichnet und kann dazu verwendet werden, Ihre Schleifen kompakter und leichter lesbar zu machen.    Ссылка

Also hast du recht. Lesbarkeit ist der Hauptgewinn hier. Für weitere Informationen über die einzelnen Schleifen oder für die erweiterte Schleife, hier ein Blogeintrag von orale .

>

Für jede verwendete die Funktionalität der Iterable<E> -Schnittstelle, also hängt die Leistung von der Implementierung ab.

    
mike 13.09.2013 14:26
quelle

Tags und Links