Overweeg:
List<String> someList = new ArrayList<String>();
// add "monkey", "donkey", "skeleton key" to someList
for (String item : someList) {
System.out.println(item);
}
Hoe zou de equivalente for
-lus eruit zien zonder de syntaxis voor elke te gebruiken?
Antwoord 1, autoriteit 100%
for (Iterator<String> i = someIterable.iterator(); i.hasNext();) {
String item = i.next();
System.out.println(item);
}
Merk op dat als u i.remove();
in uw lus moet gebruiken, of op de een of andere manier toegang moet krijgen tot de eigenlijke iterator, u de for ( : )
idioom, aangezien de eigenlijke iterator slechts wordt afgeleid.
Zoals Denis Bueno heeft opgemerkt, werkt deze code voor elk object dat de Iterable
interface.
Als de rechterkant van het for (:)
-idioom een array
is in plaats van een Iterable
-object, code gebruikt een int indexteller en vergelijkt in plaats daarvan met array.length
. Zie de Java-taalspecificatie.
Antwoord 2, autoriteit 42%
De constructie voor elk is ook geldig voor arrays. bijv.
String[] fruits = new String[] { "Orange", "Apple", "Pear", "Strawberry" };
for (String fruit : fruits) {
// fruit is an element of the `fruits` array.
}
wat in wezen gelijk is aan
for (int i = 0; i < fruits.length; i++) {
String fruit = fruits[i];
// fruit is an element of the `fruits` array.
}
Dus, algemene samenvatting:
[nsayer] Het volgende is de langere vorm van wat er gebeurt:
for(Iterator<String> i = someList.iterator(); i.hasNext(); ) { String item = i.next(); System.out.println(item); }
Merk op dat als je nodig hebt om
ik verwijder(); in uw lus, of toegang
de eigenlijke iterator op de een of andere manier, jij
kan het idioom for(: ) niet gebruiken, aangezien
de eigenlijke Iterator is slechts:
afgeleid.
Het wordt geïmpliceerd door het antwoord van nsayer, maar
het is vermeldenswaard dat de OP is voor (..)
syntaxis werkt wanneer “someList” is
alles wat implementeert
java.lang.Iterable — het heeft geen
om een lijst te zijn, of een verzameling van
java.util. Zelfs je eigen types,
daarom kan worden gebruikt met deze
syntaxis.
Antwoord 3, autoriteit 14%
De voor elke lus , toegevoegd in Java 5 (ook wel de "enhanced for loop"), komt overeen met het gebruik van een java.util.Iterator
–het is syntactische suiker voor hetzelfde. Daarom moet bij het één voor één en in volgorde lezen van elk element altijd een voor-elk worden gekozen boven een iterator, omdat dit handiger en beknopter is.
Voor elk
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());
}
Er zijn situaties waarin u rechtstreeks een Iterator
moet gebruiken. Als u bijvoorbeeld probeert een element te verwijderen terwijl u een for-each gebruikt, kan (zal?) resulteren in een ConcurrentModificationException
.
For-each vs. for-loop: basisverschillen
Het enige praktische verschil tussen for-loop en for-each is dat u in het geval van indexeerbare objecten geen toegang hebt tot de index. Een voorbeeld wanneer de basis for-loop vereist is:
for (int i = 0; i < array.length; i++) {
if(i < 5) {
// Do something special
} else {
// Do other stuff
}
}
Hoewel je handmatig een aparte index int-variabele kunt maken met for-each,
int idx = -1;
for (int i : intArray) {
idx++;
...
}
…het wordt niet aanbevolen, aangezien variable-scope is niet ideaal, en de basis for
-lus is gewoon het standaard en verwachte formaat voor dit gebruik.
For-each vs. for-loop: prestaties
Bij toegang tot collecties is een for-each aanzienlijk sneller dan de array-toegang van de basis for
-lus. Bij toegang tot arrays is de toegang via indexen echter – in ieder geval met primitieve en wrapper-arrays – aanzienlijk sneller.
Timing van het verschil tussen iterator- en indextoegang voor primitieve int-arrays
Indexen zijn 23-40 procent sneller dan iterators bij het openen van int
of Integer
arrays. Hier is de uitvoer van de testklasse onderaan dit bericht, die de getallen optelt in een primitieve-int-array van 100 elementen (A is iterator, B is 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)
Ik heb dit ook uitgevoerd voor een Integer
array, en indexen zijn nog steeds de duidelijke winnaar, maar slechts tussen 18 en 25 procent sneller.
Voor collecties zijn iterators sneller dan indexen
Voor een List
van Integers
zijn iterators echter de duidelijke winnaar. Verander gewoon de int-array in de 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});
En breng de nodige wijzigingen aan in de test-functie (int[]
naar List<Integer>
, length
naar size()
, enz.):
[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 één test zijn ze bijna gelijk, maar met collecties wint de iterator.
*Dit bericht is gebaseerd op twee antwoorden die ik schreef op Stack Overflow:
Meer informatie: Wat is efficiënter, een for-each-lus of een iterator?
De volledige testklasse
Ik heb deze les ‘vergelijk de tijd die nodig is om twee dingen te doen’ gemaakt na het lezen van deze vraag op Stack Overflow:
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
}
Antwoord 4, autoriteit 11%
Hier is een antwoord dat geen kennis van Java Iterators veronderstelt. Het is minder precies, maar het is nuttig voor het onderwijs.
Tijdens het programmeren schrijven we vaak code die er als volgt uitziet:
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]
}
Met de foreach-syntaxis kan dit algemene patroon op een natuurlijkere en minder syntactisch luidruchtige manier worden geschreven.
for(char grade : grades) { // foreach grade in grades
System.out.print(grade); // print that grade
}
Bovendien is deze syntaxis geldig voor objecten zoals lijsten of sets die geen array-indexering ondersteunen, maar die wel de Java Iterable-interface implementeren.
Antwoord 5, autoriteit 3%
De for-each-lus in Java gebruikt het onderliggende iteratormechanisme. Het is dus identiek aan het volgende:
Iterator<String> iterator = someList.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
}
Antwoord 6, autoriteit 2%
Zoals gedefinieerd in JLS voor -elke lus kan twee vormen hebben:
-
Als het type expressie een subtype is van
Iterable
, dan is de vertaling als volgt: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); }
-
Als de expressie noodzakelijkerwijs een arraytype
T[]
heeft, dan: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 heeft streams geïntroduceerd die over het algemeen beter presteren. We kunnen ze gebruiken als:
someList.stream().forEach(System.out::println);
Arrays.stream(someArray).forEach(System.out::println);
Antwoord 7, autoriteit 2%
Het wordt geïmpliceerd door het antwoord van nsayer, maar het is vermeldenswaard dat de OP’s for (..) syntaxis zal werken wanneer “someList” iets is dat java.lang.Iterable implementeert — dat doet het niet moet een lijst zijn, of een verzameling van java.util. Zelfs uw eigen typen kunnen daarom met deze syntaxis worden gebruikt.
Antwoord 8, autoriteit 2%
In Java 8-functies kunt u dit gebruiken:
List<String> messages = Arrays.asList("First", "Second", "Third");
void forTest(){
messages.forEach(System.out::println);
}
Uitvoer
First
Second
Third
Antwoord 9, autoriteit 2%
Een foreach-lussyntaxis is:
for (type obj:array) {...}
Voorbeeld:
String[] s = {"Java", "Coffe", "Is", "Cool"};
for (String str:s /*s is the array*/) {
System.out.println(str);
}
Uitvoer:
Java
Coffe
Is
Cool
WAARSCHUWING: je hebt toegang tot array-elementen met de foreach-lus, maar je kunt ze NIET initialiseren. Gebruik daarvoor de originele for
-lus.
WAARSCHUWING: U moet het type array matchen met het andere object.
for (double b:s) // Invalid-double is not String
Als je elementen wilt bewerken, gebruik dan de originele for
lus als volgt:
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";
}
Als we nu s naar de console dumpen, krijgen we:
hello
2 is cool
hello
hello
Antwoord 10, autoriteit 2%
De Java “for-each” lusconstructie zal iteratie over twee soorten objecten toestaan:
T[]
(arrays van elk type)java.lang.Iterable<T>
De Iterable<T>
interface heeft maar één methode: Iterator<T> iterator()
. Dit werkt op objecten van het type Collection<T>
omdat de interface Collection<T>
Iterable<T>
uitbreidt.
Antwoord 11
Het concept van een foreach-lus zoals genoemd in Wikipedia wordt hieronder uitgelicht:
In tegenstelling tot andere for-lusconstructies, worden foreach-lussen echter meestal
onderhoud geen expliciete teller: ze zeggen in wezen “doe dit om”
alles in deze set”, in plaats van “doe dit x keer”.
potentiële off-by-one fouten en maakt de code eenvoudiger leesbaar.
Dus het concept van een foreach-lus beschrijft dat de lus geen expliciete teller gebruikt, wat betekent dat het niet nodig is om indexen te gebruiken om in de lijst te doorlopen, dus het bespaart de gebruiker een fout voor één keer. Laten we, om het algemene concept van deze fout-door-één fout te beschrijven, een voorbeeld nemen van een lus om in een lijst te doorlopen met behulp van indexen.
// In this loop it is assumed that the list starts with index 0
for(int i=0; i<list.length; i++){
}
Maar stel dat als de lijst begint met index 1 dan zal deze lus een uitzondering genereren omdat er geen element wordt gevonden bij index 0 en deze fout wordt een fout-voor-één fout genoemd. Dus om deze fout-door-één fout te voorkomen, wordt het concept van een foreach-lus gebruikt. Er kunnen ook andere voordelen zijn, maar dit is wat ik denk dat het belangrijkste concept en voordeel is van het gebruik van een foreach-lus.
Antwoord 12
In Java 8 introduceerden ze forEach. Met behulp van de lijst kunnen kaarten worden herhaald.
Loop een lijst met voor elk
List<String> someList = new ArrayList<String>();
someList.add("A");
someList.add("B");
someList.add("C");
someList.forEach(listItem -> System.out.println(listItem))
of
someList.forEach(listItem-> {
System.out.println(listItem);
});
Loop een kaart met voor elk
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));
of
mapList.forEach((key,value)->{
System.out.println("Key : " + key + " Value : " + value);
});
Antwoord 13
for (Iterator<String> itr = someList.iterator(); itr.hasNext(); ) {
String item = itr.next();
System.out.println(item);
}
Antwoord 14
Als je oudere Java-versies gebruikt, waaronder Java 7
, kun je de forEach
-lus als volgt gebruiken.
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);
}
Volgen is de allernieuwste manier om forEach
loop in Java 8
te gebruiken
(loop een lijst met forEach
+ lambda-expressie of methodeverwijzing)
//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);
Raadpleeg deze link voor meer informatie.
https://www.mkyong.com/java8/java-8 -foreach-voorbeelden/
Antwoord 15
Hier is een equivalente uitdrukking.
for(Iterator<String> sit = someList.iterator(); sit.hasNext(); ) {
System.out.println(sit.next());
}
Antwoord 16
Houd er ook rekening mee dat het gebruik van de “foreach”-methode in de oorspronkelijke vraag enkele beperkingen heeft, zoals het niet kunnen verwijderen van items uit de lijst tijdens de iteratie.
De nieuwe for-loop is gemakkelijker te lezen en maakt een aparte iterator overbodig, maar is alleen echt bruikbaar in alleen-lezen iteratiepassages.
Antwoord 17
Een alternatief voor forEach om uw “for Each” te vermijden:
List<String> someList = new ArrayList<String>();
Variant 1 (gewoon):
someList.stream().forEach(listItem -> {
System.out.println(listItem);
});
Variant 2 (parallelle uitvoering (sneller)):
someList.parallelStream().forEach(listItem -> {
System.out.println(listItem);
});
Antwoord 18
Het voegt schoonheid toe aan je code door alle rommel in de basislus te verwijderen. Het geeft een strakke uitstraling aan je code, hieronder toegelicht.
Normale for
-lus:
void cancelAll(Collection<TimerTask> list) {
for (Iterator<TimerTask> i = list.iterator(); i.hasNext();)
i.next().cancel();
}
Voor elk gebruiken:
void cancelAll(Collection<TimerTask> list) {
for (TimerTask t : list)
t.cancel();
}
voor elk is een constructie over een verzameling die Iterator implementeert. Onthoud dat uw verzameling Iterator moet implementeren; anders kun je het niet gebruiken met voor-elk.
De volgende regel wordt gelezen als “voor elke TimerTask t in lijst.“
for (TimerTask t : list)
Er is minder kans op fouten in het geval van for-each. U hoeft zich geen zorgen te maken over het initialiseren van de iterator of het initialiseren van de lusteller en het beëindigen ervan (waar er ruimte is voor fouten).
Antwoord 19
Vóór Java 8 moet u het volgende gebruiken:
Iterator<String> iterator = someList.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
}
Met de introductie van Streams in Java 8 kun je echter hetzelfde doen in veel minder syntaxis. Voor uw someList
kunt u bijvoorbeeld het volgende doen:
someList.stream().forEach(System.out::println);
Je kunt meer vinden over streams hier.
Antwoord 20
Het zou er ongeveer zo uitzien. Heel cru.
for (Iterator<String> i = someList.iterator(); i.hasNext(); )
System.out.println(i.next());
Er is een goede beschrijving van voor elk in de Zondocumentatie.
Antwoord 21
Zoals zoveel goede antwoorden al zeiden, moet een object de Iterable interface
implementeren als het een for-each
-lus wil gebruiken.
Ik zal een eenvoudig voorbeeld posten en op een andere manier proberen uit te leggen hoe een for-each
-lus werkt.
Het for-each
lusvoorbeeld:
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);
}
}
}
Als we javap
gebruiken om deze klasse te decompileren, krijgen we dit bytecode-voorbeeld:
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;
Zoals we kunnen zien aan de laatste regel van het voorbeeld, converteert de compiler automatisch het gebruik van for-each
trefwoord naar het gebruik van een Iterator
tijdens het compileren . Dat kan verklaren waarom een object, dat de Iterable interface
niet implementeert, een Exception
zal genereren wanneer het de for-each
-lus probeert te gebruiken .
Antwoord 22
De Java voor elke lus (ook bekend als Enhanced for Loop) is een vereenvoudigde versie van een for-lus. Het voordeel is dat er minder code hoeft te worden geschreven en minder variabelen hoeven te worden beheerd. Het nadeel is dat je geen controle hebt over de stapwaarde en geen toegang hebt tot de loop-index in de loop-body.
Ze kunnen het beste worden gebruikt wanneer de stapwaarde een eenvoudige stapgrootte van 1 is en wanneer u alleen toegang nodig hebt tot het huidige luselement. Als u bijvoorbeeld elk element in een array of verzameling moet doorlopen zonder voor of achter het huidige element te kijken.
Er is geen lusinitialisatie, geen booleaanse voorwaarde en de stapwaarde is impliciet en is een eenvoudige verhoging. Dit is waarom ze zo veel eenvoudiger worden beschouwd dan gewone for-loops.
Verbeterde for-lussen volg deze volgorde van uitvoering:
1) loop body
2) herhaal vanaf stap 1 totdat de hele array of verzameling is doorlopen
Voorbeeld Integer Array
int [] intArray = {1, 3, 5, 7, 9};
for(int currentValue : intArray) {
System.out.println(currentValue);
}
De variabele currentValue bevat de huidige waarde die wordt doorgelust in de intArray-array. Merk op dat er geen expliciete stapwaarde is – het is altijd een verhoging met 1.
De dubbele punt kan worden gezien als in . Dus de verbeterde for-lusdeclaratie stelt: loop over intArray en sla de huidige array int-waarde op in de currentValue-variabele.
Uitvoer:
1
3
5
7
9
Voorbeeld String Array
We kunnen de for-each-lus gebruiken om een reeks strings te doorlopen. De lusverklaring stelt: loop over myStrings String-array en sla de huidige String-waarde op in de currentString-variabele.
String [] myStrings = {
"alpha",
"beta",
"gamma",
"delta"
};
for(String currentString : myStrings) {
System.out.println(currentString);
}
Uitvoer:
alpha
beta
gamma
delta
Voorbeeld Lijst
De verbeterde for-lus kan ook als volgt worden gebruikt om een java.util.List te doorlopen:
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);
}
De lusdeclaratie stelt: loop over myList List of Strings en sla de huidige List-waarde op in de currentItem-variabele.
Uitvoer:
alpha
beta
gamma
delta
Voorbeeld Instellen
De verbeterde for-lus kan ook als volgt worden gebruikt om een java.util.Set te doorlopen:
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);
}
De lusverklaring stelt: loop over mySet Set of Strings en sla de huidige Set-waarde op in de currentItem-variabele. Merk op dat aangezien dit een Set is, dubbele String-waarden niet worden opgeslagen.
Uitvoer:
alpha
delta
beta
gamma
Bron: Loops in Java Ultieme gids
Antwoord 23
Zoals veel andere antwoorden correct aangeven, is de for
each
loop
gewoon syntactische suiker over dezelfde oude for
loop
en de compiler vertaalt het naar dezelfde oude for-lus.
javac (open jdk) heeft een schakelaar -XD-printflat
, die een java-bestand genereert waarin alle syntactische suikers zijn verwijderd. de complete opdracht ziet er zo uit
javac -XD-printflat -d src/ MyFile.java
//-d is used to specify the directory for output java file
Dus laten we de syntactische suiker verwijderen
Om deze vraag te beantwoorden, heb ik een bestand gemaakt en twee versies van for
each
geschreven, een met een array
en een andere met een List
. mijn java
-bestand zag er zo uit.
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);
}
}
}
Toen ik dit bestand compiled
met bovenstaande schakelaar, kreeg ik de volgende uitvoer.
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);
}
}
}
}
Je kunt zien dat samen met de andere syntactische suiker (Autoboxing) voor elke loops is veranderd in eenvoudige loops.
Antwoord 24
public static Boolean Add_Tag(int totalsize)
{ List<String> fullst = new ArrayList<String>();
for(int k=0;k<totalsize;k++)
{
fullst.addAll();
}
}
Antwoord 25
Het Java-idioom voor elk kan alleen worden toegepast op arrays of objecten van het type *Iterable. Dit idioom is impliciet omdat het echt wordt ondersteund door een Iterator. De Iterator wordt geprogrammeerd door de programmeur en gebruikt vaak een integer-index of een knooppunt (afhankelijk van de datastructuur) om zijn positie bij te houden. Op papier is het langzamer dan een gewone for-loop, althans voor “lineaire” structuren zoals arrays en lijsten, maar het biedt meer abstractie.
Antwoord 26
Dit ziet er gek uit, maar het werkt
List<String> someList = new ArrayList<>(); //has content
someList.forEach(System.out::println);
Dit werkt. Magie
Antwoord 27
Ik denk dat dit zal werken:
for (Iterator<String> i = someList.iterator(); i.hasNext(); ) {
String x = i.next();
System.out.println(x);
}
Antwoord 28
De code zou zijn:
import java.util.ArrayList;
import java.util.List;
public class ForLoopDemo {
public static void main(String[] args) {
List<String> someList = new ArrayList<String>();
someList.add("monkey");
someList.add("donkey");
someList.add("skeleton key");
//Iteration using For Each loop
System.out.println("Iteration using For Each loop:");
for (String item : someList) {
System.out.println(item);
}
//Iteration using normal For loop
System.out.println("\nIteration using normal For loop:");
for (int index = 0; index < someList.size(); index++) {
System.out.println(someList.get(index));
}
}
}