Hoe werkt de Java ‘for each’-lus?

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.

[Denis Bueno]

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;
/**
   &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
}

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:

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

LEAVE A REPLY

Please enter your comment!
Please enter your name here

five + 12 =

Other episodes