# For-Each Loop



## sousou (23. Sep 2009)

Hallo,


hab ein wenig schwieriegkeiten bei der For-Each Loop also der for each Schleife. Und zwar Weiß ich wiedie normale For-Schleife funktioniert.. die for each versteh ich jedoch nicht.....

Beispiel:

Normale forschleife:
[JAVA=42]
String [] wochentage = { "montag", "dienstag", mittwoch", "freitag", "samstag", "sonntag" };

for(int i = 0; i < 10; i++) {
System.out.println(i.+"Wochentag:"+wochentage_);
}
[/code]

Wie könnte ich jetzt eine normale for each Schleife machen, die den selben effekt bringt wie diese normale For - Schleife.



Danke im voraus_


----------



## 0x7F800000 (23. Sep 2009)

Dein code enthält mindestens 2 Syntaxfehler...

Wenn du den laufindex benötigst, taugt die foreach-schleife nichts. Bei einer Foreach schleife kannst du auf den Index nicht mehr zugreifen. Aber da dieser meistens eh nur rumnervt, oder gar nicht vorhanden ist, benutzt man oft eben die viel kürzere foreach-schleife.


----------



## Painii (23. Sep 2009)

```
for(int i = 0; i < 10; i++) { 
 System.out.println(i.+"Wochentag:"+wochentage[i]);
}
//gleich wie
int i =0;
for(String wochentag:wochentage){
 System.out.println((++i) +". Wochentag: "+wochentag);
}
```

In der for-each-schleife wird also immer noch eine extra-variable benutzt aus dem array/collection.
Die "normale" for-schleife kann auch leer sein, also keine extra hilfs-variablen haben, oder auch mehr als eine haben.

edit: ja, ein e vergessen, wollte doch schnell noch den beitrag schreiben vorm essen


----------



## faetzminator (23. Sep 2009)

[c]for (String wochentag : wochentage) {[/c] wärs natürlich


----------



## C_A (25. Feb 2010)

Ich habe mal eine Frage: in den meisten Lehrbüchern, aber auch in zahlreichen Beispielen im Internet wird mit for-Schleifen über Arrays iteriert, obwohl der Index gar nicht benötigt wird. Ich hätte in vielen Beispielen eine for-each-Schleife erwartet. 

Gibt es Gründe gegen eine for-each-Schleife? Gibt es Nachteile gegenüber der for-Schleife?


----------



## nrg (25. Feb 2010)

Florian_ hat gesagt.:


> Gibt es Gründe gegen eine for-each-Schleife? Gibt es Nachteile gegenüber der for-Schleife?



nicht, dass ich wüsste. Wenn man den Index nicht braucht, spricht nichts gegen eine for-each. 

Ich vermute, dass die Lehrbücher es einfach einfach halten wollten


----------



## eRaaaa (25. Feb 2010)

oder das Buch aus der Zeit vor Java 5 stammt  (oder man den Index zwar nicht braucht, aber man vllt nur jedes zweite Element lesen möchte i+=2 ..oder Allgemein..nicht alle )


----------



## C_A (25. Feb 2010)

Na gut, ist mir nur aufgefallen. Manchmal habe ich einfach den Eindruck, dass for-each-Schleifen irgendwas eklig an sich haben müssen. sozusagen die Schmuddelkinder der Programmierer-Werkzeuge.


----------



## Ziegenpeter (26. Feb 2010)

Nur nochmal allgemein, da es so noch nirgendwo steht:


```
for(Typ variable : collection){
...
}
```
wobei Typ der Typ der Elemente in deiner Collection ist, variable ist ein von dir gewählter Variablenname und collection ist Name deiner Collection über die iteriert werden soll. Mit jedem Schleifendurchlauf steht in 'variable' dann ein Eintrag aus deiner Collection.


----------



## eRaaaa (26. Feb 2010)

Florian_ hat gesagt.:


> Na gut, ist mir nur aufgefallen. Manchmal habe ich einfach den Eindruck, dass for-each-Schleifen irgendwas eklig an sich haben müssen. sozusagen die Schmuddelkinder der Programmierer-Werkzeuge.



Nein im Gegenteil! Sun *hust* empfiehlt sogar man solle am Besten immer for-each nehmen, sofern man dies auch ohne Probleme tun kann.
Manchmal braucht man aber auch den Iterator (an den man so ja nicht ran kommt/sieht) , dann kann man for-each halt auch nicht benutzen...


----------



## Landei (26. Feb 2010)

In unserem alten Code stehen fast überall Iteratoren drin, und in 95% der Fälle lassen die sich durch for-each loops ersetzen (was ich meistens auch tue). 

Kurz gesagt: for-each ist besser als for ist besser als while und/oder Iterator.
- for-each ist besser als for, weil man sich mit dem Index nicht vermachen kann.
- die beiden for-Varianten sind besser als while oder do, weil die Schleifenvariable oder der Iterator nicht im umgebenden Block sichtbar ist, was zu subtilen Fehlern führen kann:


```
Iterator it1 = myBlaList.itererator();
while(it1.hasNext()) {
   Bla bla = (Bla)it1;
   doSomething(bla);
}
...
Iterator it2 = myOtherBlaList.itererator();
while(it1.hasNext()) {
   Bla bla = (Bla)it1;
   doSomethingElse(bla);
}
```
Tatsächlich sind mir solche Fehler schon öfter untergekommen.


----------



## faetzminator (26. Feb 2010)

Leider finde ich die Aussage gerade nirgends, aber man sollte AFAIK auf foreachs mit Arrays verzichten (man sollte allgemein auf Arrays verzichten  ), da intern diese zuerst in ein Iterable Object umgewandelt werden. Kann jemand meine Aussage bestätigen?


----------



## eRaaaa (26. Feb 2010)

Mhm, also laut Java Blog Buch : 06.08 Iterable, for-each und Iterator wird daraus eher eine normale for. Hab`s eben auch mal decompiliert, da sah`s genau so aus. Auch die Insel sagt:





			
				http://openbook.galileocomputing.de/javainsel8/javainsel_03_010.htm#mj0cca794d575714a3dbff8db667e0ab85 hat gesagt.:
			
		

> Intern setzt der Compiler diese erweiterte for-Schleife ganz klassisch um, sodass der Bytecode unter beiden Varianten gleich ist.



??


----------



## faetzminator (26. Feb 2010)

Oke, dann lag mir da wohl eine Fehlinformation vor oder mein Gedächnis spielt mir einen Streich. Trotzdem ändert dies nichts an meiner Aussage, dass Arrays irgendwie nicht unbedingt ins OO-Konzept passen - aber dies ist eine andere Diskussion  .


----------



## ThreadPool (26. Feb 2010)

eRaaaa hat gesagt.:


> Mhm, also laut Java Blog Buch : 06.08 Iterable, for-each und Iterator wird daraus eher eine normale for. Hab`s eben auch mal decompiliert, da sah`s genau so aus. Auch die Insel sagt:
> 
> ??



Was da rauskommt ist JVM spezifisch, die JLS referiert unter Punkt 14.14.2 nur über die "inhaltliche
Bedeutung". Bytecode-mäßig (bei mir 32Bit JVM, Win XP Ver. 1.6_01) braucht test2() fünf Operationen 
mehr wobei das hauptsächlich ein paar zusätzliche Variablen sind. Kompiliert wurde mit -_g:none -
target 1.6_. Zum Anzeigen des Bytecodes habe ich _javap -c_ verwendet


```
int a[]={1,2,3};
	int b[]={4,5,6};
	public void test1(){
		for(int i = 0; i < a.length; i++){
			System.out.println(a[i]);
		}
	}

	public void test2(){
		for(int i:b){
			System.out.println(i);
		}
	}
```

Nur die nackten for's.

```
int a[]={1,2,3};
	int b[]={4,5,6};
	public void test1(){
		for(int i = 0; i < a.length; i++){
		}
	}

	public void test2(){
		for(int i:b){
		}
	}
```

Und der Bytecode dazu.


```
public void test1();
  Code:
   0:	iconst_0
   1:	istore_1
   2:	iload_1
   3:	aload_0
   4:	getfield	#2; //Field a:[I
   7:	arraylength
   8:	if_icmpge	17
   11:	iinc	1, 1
   14:	goto	2
   17:	return

public void test2();
  Code:
   0:	aload_0
   1:	getfield	#3; //Field b:[I
   4:	astore_1
   5:	aload_1
   6:	arraylength
   7:	istore_2
   8:	iconst_0
   9:	istore_3
   10:	iload_3
   11:	iload_2
   12:	if_icmpge	26
   15:	aload_1
   16:	iload_3
   17:	iaload
   18:	istore	4
   20:	iinc	3, 1
   23:	goto	10
   26:	return
```

Und nur FYI, das Kürzeste was man so hinbekommt ist IMHO wenn das Array von hinten
abgearbeitet wird. Dann kann man noch eine Operation sparen zum inkrementierenden 
for.


```
public void test4(){
		for(int i = a.length; --i >=0;){
		}
	}
```


```
public void test4();
  Code:
   0:	aload_0
   1:	getfield	#2; //Field a:[I
   4:	arraylength
   5:	istore_1
   6:	iinc	1, -1
   9:	iload_1
   10:	iflt	16
   13:	goto	6
   16:	return
```


----------



## Antoras (26. Feb 2010)

Wobei man sich hier natürlich die Frage stellen muss wie viel nativer Code von den Schleifen übrig bleib. Ich schätze mal, dass de Java-Compiler im Vergleich zu z.B. einem C-Compiler relative wenig optimieren kann, da ja die Plattformunabhängigkeit gewährt bleiben muss. Erst der Java-Interpreter bzw. die JVM dürften mit dem Optimieren richtig loslegen.
Von dem her würde ich mir da gar keine Gedanken machen welche for-Schleife man da am besten einsetzen soll.


----------



## ThreadPool (27. Feb 2010)

Antoras hat gesagt.:


> Von dem her würde ich mir da gar keine Gedanken machen welche for-Schleife man da am besten einsetzen soll.



Bei dem enhanced for sollte man zumindest nachsehen wie der Iterator des Ziels implementiert ist. Mir
sind schon Iteratoren untergekommen bei deren Erstellung noch so einiges getan wurde und die Kosten
dementsprechend hoch waren. Es wurde jedoch übersehen das der "teure" Iterator nicht für alle
Operationen benötigt wurde, was im Endeffekt 3% Geschwindigkeitsunterschied ausgemacht hat. Das
ist nicht übermäßig wird da manch einer sagen, der Meinung bin ich auch. Ich möchte nur darauf
hinweisen das man in der freien Wildbahn die Augen offen halten sollte. Und natürlich gilt wie auch in
meinem Beispiel _First make it right. Then make it fast._


----------

