Jak działa pętla Java 'for each'?

Rozważmy:

List<String> someList = new ArrayList<String>();
// add "monkey", "donkey", "skeleton key" to someList
for (String item : someList) {
    System.out.println(item);
}

Jak wyglądałaby równoważna pętla for bez użycia dla każdej składni?

Author: Jay R., 2008-09-17

27 answers

for (Iterator<String> i = someIterable.iterator(); i.hasNext();) {
    String item = i.next();
    System.out.println(item);
}

Zauważ, że jeśli chcesz użyć i.remove(); w swojej pętli lub uzyskać dostęp do rzeczywistego iteratora w jakiś sposób, nie możesz użyć idiomu for ( : ), ponieważ rzeczywisty iterator jest tylko wnioskowany.

Jak zauważył Denis Bueno, kod ten działa dla każdego obiektu, który implementuje Iterable Interfejs .

Ponadto, jeśli prawa strona idiomu for (:) jest obiektem array, a nie obiektem Iterable, kod wewnętrzny używa licznika indeksu int i zamiast tego sprawdza array.length. Zobacz też Specyfikacja Języka Java .

 1214
Author: nsayer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-03 16:16:09

Konstrukcja dla każdego jest również ważna dla tablic. np.

String[] fruits = new String[] { "Orange", "Apple", "Pear", "Strawberry" };

for (String fruit : fruits) {
    // fruit is an element of the `fruits` array.
}

Który jest zasadniczo odpowiednikiem

for (int i = 0; i < fruits.length; i++) {
    String fruit = fruits[i];
    // fruit is an element of the `fruits` array.
}

Tak więc, ogólne podsumowanie:
[nsayer] Oto dłuższa forma tego, co się dzieje:

for(Iterator<String> i = someList.iterator(); i.hasNext(); ) {
  String item = i.next();
  System.out.println(item);
}

Zwróć uwagę, że jeśli potrzebujesz użyć I. remove (); in your loop, or access rzeczywisty iterator w jakiś sposób, ty nie można użyć idiomu for (:), ponieważ rzeczywisty Iterator jest jedynie wywnioskować.

[Denis Bueno]

To wynika z odpowiedzi nsayer, ale warto zauważyć, że OP jest dla(..) składnia będzie działać, gdy "someList" jest wszystko, co implementuje java.lang.Iterable -- nie ma być listą, albo jakąś kolekcją z java.util. Nawet własne typy, dlatego może być stosowany z tym składnia.

 510
Author: Mikezx6r,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:06:59

The foreach loop , dodany w Java 5 (zwany także "enhanced For loop"), jest odpowiednikiem java.util.Iterator--to cukier składniowy do tego samego. Dlatego podczas czytania każdego elementu, Jeden po drugim i w kolejności, foreach powinien być zawsze wybierany zamiast iteratora, ponieważ jest wygodniejszy i bardziej zwięzły.

Foreach

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());
}

Są sytuacje, w których musisz użyć Iterator bezpośrednio. Na przykład, próba Usuń element używając foreach can (will?) wynik w ConcurrentModificationException.

foreach vs. for : podstawowe różnice

Jedyną praktyczną różnicą między for a foreach jest to, że w przypadku obiektów indeksowalnych nie masz dostępu do indeksu. Przykład, gdy podstawowa pętla for jest wymagana:

for(int i = 0; i < array.length; i++) {
   if(i < 5) {
      // Do something special
   }  else {
      // Do other stuff
   }
}

Chociaż można ręcznie utworzyć osobny indeks int-zmienna z foreach,

int idx = -1;
for(int i : intArray) {
   idx++;
   ...
}

Nie jest to zalecane, ponieważ zakres zmienny nie jest idealny, a Podstawowa pętla for jest po prostu standardowym i oczekiwanym formatem dla tego przypadku użycia.

foreach vs. for: wydajność

Podczas uzyskiwania dostępu do kolekcji, foreach jest znacznie szybszy niż podstawowy dostęp pętli for. Jednak podczas uzyskiwania dostępu do tablic-przynajmniej w przypadku tablic prymitywnych i wrapper-arrays-dostęp przez indeksy jest znacznie szybszy.

Różnica między iteratorem a indeksem dostępu dla prymitywnych int-arrays

Indeksy są 23-40 procent szybciej niż Iteratory przy dostępie do tablic int lub Integer. Poniżej znajduje się wyjście z klasy testing na dole tego posta, która sumuje liczby w 100-elementowej tablicy primitive-int (a to iterator, B to indeks): {]}

[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)

Uruchomiłem również to dla Integer tablicy, i indeksy są nadal wyraźnym zwycięzcą, ale tylko między 18 a 25 procent szybciej.

Dla zbiorów Iteratory są szybsze niż indeksy

Dla List z Integers, jednak Iteratory są wyraźnym zwycięzcą. Po prostu zmień tablicę int w klasie testowej na:

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});

I dokonać niezbędnych zmian w funkcji testowej (int[] do List<Integer>, length do size(), itd.):

[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)

W jednym teście są prawie równoważne, ale ze zbiorami iterator wygrywa.

*ten post jest oparty na dwóch odpowiedziach, które napisałem na Stack Overflow:

Trochę więcej informacji: która jest bardziej wydajna, pętla for-each, czy iterator?

Pełna klasa testowa

Stworzyłem tę klasę porównywania-czasu-potrzebny-do-zrobienia-dowolnych-dwóch-rzeczy po przeczytaniu tego pytania na 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

}
 172
Author: aliteralmind,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:35:45

Oto odpowiedź, która nie zakłada znajomości iteratorów Javy. Jest mniej precyzyjny, ale przydatny w edukacji.

Podczas programowania często piszemy kod, który wygląda następująco:

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]
}
Składnia foreach pozwala na zapisanie tego wspólnego wzorca w bardziej naturalny i mniej hałaśliwy sposób.
for(char grade : grades) {   // foreach grade in grades
    System.out.print(grade); // print that grade
}

Dodatkowo ta składnia jest ważna dla obiektów takich jak listy lub zestawy, które nie obsługują indeksowania tablic, ale które implementują Javę Iterowalny interfejs.

 130
Author: MRocklin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:12:45

Pętla for-each w Javie wykorzystuje podstawowy mechanizm iteratora. Jest więc identyczny z następującym:

Iterator<String> iterator = someList.iterator();

while (iterator.hasNext()) {
  String item = iterator.next();
  System.out.println(item);
}
 42
Author: toluju,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:04:16

Zgodnie z definicją w JLS for-każda pętla może mieć dwie formy:

  1. Jeśli typ wyrażenia jest podtypem Iterable, to translacja jest następująca:

    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. Jeśli wyrażenie koniecznie ma typ tablicy T[] to:

    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 wprowadziła strumienie, które działają ogólnie lepiej. Możemy ich używać jako:

someList.stream().forEach(System.out::println);
Arrays.stream(someArray).forEach(System.out::println);
 25
Author: akhil_mittal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-20 09:12:52

Wynika to z odpowiedzi nsayer, ale warto zauważyć, że OP jest dla (..) składnia będzie działać, gdy "someList" to cokolwiek implementującego Javę.lang.Iterable - nie musi to być lista, ani jakaś kolekcja z Javy.util. Z tą składnią można więc korzystać nawet z własnych typów.

 25
Author: EfForEffort,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:05:36

W Javie 8 funkcji można użyć tego:

List<String> messages = Arrays.asList("First", "Second", "Third");

void forTest(){
    messages.forEach(System.out::println);
}

Wyjście

First
Second
Third
 24
Author: Jrovalle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-25 15:43:15

Składnia pętli foreach to:

for (type obj:array) {...}

Przykład:

String[] s = {"Java", "Coffe", "Is", "Cool"};
for (String str:s /*s is the array*/) {
    System.out.println(str);
}

Wyjście:

Java
Coffe
Is
Cool

Ostrzeżenie: możesz uzyskać dostęp do elementów tablicy za pomocą pętli foreach, ale nie możesz ich zainicjować. Użyj do tego oryginalnej pętli for.

Ostrzeżenie: musisz dopasować typ tablicy do innego obiektu.

for (double b:s) // Invalid-double is not String

Jeśli chcesz edytować elementy, użyj oryginalnej pętli for w następujący sposób:

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";
}

Teraz, jeśli wrzucimy s do konsoli, otrzymamy:

hello
2 is cool
hello
hello
 23
Author: PrivateName,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:16:36

Konstrukcja pętli Java "for-each" pozwoli na iterację dwóch typów obiektów:

  • T[] (tablice dowolnego typu)
  • java.lang.Iterable<T>

Interfejs Iterable<T> posiada tylko jedną metodę: Iterator<T> iterator(). Działa to na obiektach typu Collection<T>, ponieważ interfejs Collection<T> rozszerza Iterable<T>.

 21
Author: Ryan Delucchi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 18:04:18

Pojęcie pętli foreach, jak wspomniano w Wikipedii, jest podkreślone poniżej:

W przeciwieństwie do innych konstrukcji pętli for, pętle forach Zwykle utrzymanie bez wyraźnego licznika: zasadniczo mówią "zrób to, aby wszystko w tym zestawie", a nie "zrób to x razy". Pozwala to uniknąć potencjalne błędy off-by-one i sprawia, że kod jest łatwiejszy do odczytania.

Tak więc pojęcie pętli foreach opisuje, że pętla nie używa żadnego jawnego licznika co oznacza, że nie ma potrzeby używania indeksów do poruszania się po liście, dzięki czemu oszczędza to Użytkownika od błędu off-by-one. Aby opisać ogólne pojęcie tego błędu off-by-one, weźmy przykład pętli do przemierzania listy za pomocą indeksów.

// In this loop it is assumed that the list starts with index 0
for(int i=0; i<list.length; i++){

}

Ale załóżmy, że jeśli lista zaczyna się od indeksu 1, to ta pętla wyrzuci wyjątek, ponieważ nie znajdzie elementu w indeksie 0 i ten błąd jest nazywany błędem off-by-one. Aby więc uniknąć tego błędu, koncepcja foreach pętla jest używana. Mogą być też inne zalety, ale to jest to, co moim zdaniem jest główną koncepcją i zaletą korzystania z pętli foreach.

 16
Author: oneConsciousness,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:14:37

W Javie 8 wprowadzili forEach. Za pomocą listy można zapętlać Mapy.

Loop a List using for each

List<String> someList = new ArrayList<String>();
someList.add("A");
someList.add("B");
someList.add("C");

someList.forEach(listItem -> System.out.println(listItem))

Lub

someList.forEach(listItem-> {
     System.out.println(listItem); 
});

Loop a Map using for each

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));

Lub

mapList.forEach((key,value)->{
    System.out.println("Key : " + key + " Value : " + value);
});
 16
Author: vivekkurien,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-30 13:23:15
for (Iterator<String> itr = someList.iterator(); itr.hasNext(); ) {
   String item = itr.next();
   System.out.println(item);
}
 12
Author: Roger Lindsjö,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-19 09:58:20

Używając starszych wersji Javy, w tym Java 7 Można używać pętli foreach w następujący sposób.

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);
        }

Poniżej znajduje się najnowszy sposób użycia pętli foreach w Java 8

(loop a List with forEach + lambda expression or method reference)

//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);

Więcej informacji można znaleźć pod tym linkiem.

Https://www.mkyong.com/java8/java-8-foreach-examples/

 12
Author: Dulith De Costa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-21 11:05:15

Oto równoważne wyrażenie.

for(Iterator<String> sit = someList.iterator(); sit.hasNext(); ) {
    System.out.println(sit.next());
}
 10
Author: Hank,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 16:48:10

Zauważ również, że użycie metody "foreach" w pytaniu pierwotnym ma pewne ograniczenia, takie jak niemożność usunięcia elementów z listy podczas iteracji.

Nowa pętla for jest łatwiejsza do odczytania i eliminuje potrzebę oddzielnego iteratora, ale jest naprawdę użyteczna tylko w przejściach iteracji tylko do odczytu.

 10
Author: billjamesdev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 16:53:52

Alternatywa dla forEach w celu uniknięcia "dla każdego":

List<String> someList = new ArrayList<String>();

Wariant 1 (zwykły):

someList.stream().forEach(listItem -> {
    System.out.println(listItem);
});

Variant 2 (parallel execution (faster)):

someList.parallelStream().forEach(listItem -> {
    System.out.println(listItem);
});
 9
Author: Alexander Drobyshevsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:38:25

Dodaje piękno twojemu kodowi, usuwając wszystkie podstawowe zapętlenia. Daje to czysty wygląd kodu, uzasadniony poniżej.

Normal for loop:

void cancelAll(Collection<TimerTask> list) {
    for (Iterator<TimerTask> i = list.iterator(); i.hasNext();)
         i.next().cancel();
}

Użycie for-each:

void cancelAll(Collection<TimerTask> list) {
    for (TimerTask t : list)
        t.cancel();
}

Dla-każdy jest konstruktem nad zbiorem, który implementuje Iterator . Pamiętaj, że Twoja kolekcja powinna zaimplementować Iterator ; w przeciwnym razie nie możesz go używać Z for-each.

Następujący wiersz jest odczytywany jako "dla każdej TimerTask t na liście."

for (TimerTask t : list)

Jest mniejsza szansa na błędy w przypadku for-each. Nie musisz się martwić o zainicjalizowanie iteratora lub zainicjowanie licznika pętli i jego zakończenie (tam gdzie jest miejsce na błędy).

 8
Author: Manohar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-31 20:02:43

Przed uruchomieniem Java 8, należy użyć:

Iterator<String> iterator = someList.iterator();

while (iterator.hasNext()) {
    String item = iterator.next();
    System.out.println(item);
}

Jednak wraz z wprowadzeniem strumieni w Javie 8 można zrobić to samo w znacznie mniejszej składni. Na przykład dla twojego someList możesz zrobić:

someList.stream().forEach(System.out::println);

Więcej o streamach znajdziesz tutaj .

 8
Author: stackFan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:40:15

Wyglądałoby to mniej więcej tak. Bardzo chytry.

for (Iterator<String> i = someList.iterator(); i.hasNext(); )
        System.out.println(i.next());

Jest dobry writeup na dla każdego w dokumentacji Sun .

 7
Author: Pete,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 13:05:04

Jak wiele dobrych odpowiedzi powiedziało, obiekt musi zaimplementować Iterable interface, jeśli chce użyć pętli for-each.

Zamieszczę prosty przykład i postaram się wyjaśnić w inny sposób, jak działa pętla for-each.

Przykład pętli for-each:

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);
        }
    }
}

Następnie, jeśli użyjemy javap do dekompilacji tej klasy, otrzymamy próbkę kodu bajtowego:

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;

Jak widać z ostatniego wiersza próbki, kompilator automatycznie przekonwertuje użycie słowa kluczowego for-each na użycie Iterator w czasie kompilacji. Może to wyjaśniać, dlaczego obiekt, który nie implementuje Iterable interface, rzuci Exception, gdy spróbuje użyć pętli for-each.

 6
Author: L Joey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-31 20:05:03

The Java for each loop (aka enhanced for loop) jest uproszczoną wersją pętli for. Zaletą jest to, że jest mniej kodu do napisania i mniej zmiennych do zarządzania. Minusem jest to, że nie masz kontroli nad wartością kroku i nie masz dostępu do indeksu pętli wewnątrz ciała pętli.

Są one najlepiej używane, gdy wartość step jest prostym przyrostem o 1 i gdy potrzebujesz tylko dostępu do elementu Pętli Prądowej. Na przykład, jeśli musisz zapętlić każdy element w tablica lub Kolekcja bez zaglądania do przodu lub za bieżącym elementem.

Nie ma inicjalizacji pętli, nie ma warunku logicznego, a wartość kroku jest niejawna i jest prostym przyrostem. Dlatego są one uważane za o wiele prostsze niż zwykłe dla pętli.

Enhanced for loops follow this order of execution:

1) Korpus pętli

2) powtórz od kroku 1 do przejścia całej tablicy lub kolekcji

Przykład-Integer Array

int [] intArray = {1, 3, 5, 7, 9};
for(int currentValue : intArray) {
  System.out.println(currentValue);
}

Zmienna currentValue przechowuje bieżącą wartość zapętloną w tablicy intArray. Zauważ, że nie ma jawnej wartości kroku-zawsze jest to przyrost o 1.

Dwukropek może oznaczać "w". Tak więc deklaracja enhanced for loop stwierdza: loop over intArray i zapisuje bieżącą tablicę int wartość w zmiennej currentValue.

Wyjście:

1
3
5
7
9

Przykład-String Array

Możemy użyć for - każda pętla do iteracji nad tablicą łańcuchów. Deklaracja pętli mówi: loop over myStrings String array i przechowuje bieżącą wartość W zmiennej currentString.

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

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

Wyjście:

alpha
beta
gamma
delta

Example-List

Pętla enhanced for może być również używana do iteracji w Javie.util.Lista wygląda następująco:
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);
}

Deklaracja loop stwierdza: loop over myList List of Strings and store the current List value in the zmienna currentItem.

Wyjście:

alpha
beta
gamma
delta

Przykład-Zestaw

Pętla enhanced for może być również używana do iteracji w Javie.util.Ustaw w następujący sposób:
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);
}

Deklaracja loop stwierdza: loop over Myset Set of Strings and store the current set value in The currenttitem variable. Zauważ, że ponieważ jest to zbiór, zduplikowane wartości łańcuchowe nie są przechowywane.

Wyjście:

alpha
delta
beta
gamma

Źródło: pętle w Javie-Ultimate Przewodnik

 6
Author: gomisha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-02 13:11:27
public static Boolean Add_Tag(int totalsize)
{ List<String> fullst = new ArrayList<String>();
            for(int k=0;k<totalsize;k++)
            {
              fullst.addAll();
            }
}
 4
Author: Santhosh Rajkumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-27 11:55:00

Idiom Java for-each może być stosowany tylko do tablic lub obiektów typu *Iterable. Ten idiom to implicit Jak to naprawdę wspierane przez iteratora. Iterator jest programowany przez programistę i często używa indeksu integer lub węzła (w zależności od struktury danych) do śledzenia jego pozycji. Na papierze jest wolniejszy niż zwykła pętla for, a najmniej dla" liniowych " struktur, takich jak tablice i listy, ale zapewnia większą abstrakcję.

 3
Author: TheArchon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-18 17:43:28

Jak wiele innych odpowiedzi poprawnie stwierdza, for each loop jest tylko składniowy cukier nad tym samym starym for loop a kompilator tłumaczy to na tą samą starą pętlę for.

javac (open jdk) posiada przełącznik -XD-printflat, który generuje plik java z usuniętym cukrem składniowym. pełna Komenda wygląda tak:

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

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

więc usuńmy cukier składniowy

Aby odpowiedzieć na to pytanie, utworzyłem plik i napisał dwie wersje for each, jeden z array i drugi z list. mój java plik wyglądał tak.

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);
        }
    }
}

Kiedy compiled ten plik z powyższym przełącznikiem, otrzymałem następujące wyjście.

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);
            }
        }
    }
}

Widać, że wraz z innym cukrem składniowym (Autoboxingiem) dla każdej pętli zmieniono na proste pętle.

 3
Author: mightyWOZ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-17 16:01:30

To wygląda szalenie, ale hej to działa

List<String> someList = new ArrayList<>(); //has content
someList.forEach(System.out::println);
To działa. Magia
 2
Author: Rei Brown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-29 08:38:51

Myślę, że to zadziała:

for (Iterator<String> i = someList.iterator(); i.hasNext(); ) {
   String x = i.next();
   System.out.println(x);
}
 0
Author: nabayram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-26 18:09:05