Bagaimana cara kerja loop 'untuk setiap' Java?

1499

Mempertimbangkan:

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

Seperti apa forloop ekivalen itu tanpa menggunakan sintaks untuk masing-masing ?

Jay R.
sumber
Per JLS memiliki dua bentuk: stackoverflow.com/a/33232565/1216775
akhil_mittal

Jawaban:

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

Perhatikan bahwa jika Anda perlu menggunakan i.remove();dalam loop Anda, atau mengakses iterator yang sebenarnya dalam beberapa cara, Anda tidak dapat menggunakan for ( : )idiom, karena iterator yang sebenarnya hanya disimpulkan.

Seperti yang dicatat oleh Denis Bueno, kode ini berfungsi untuk objek apa pun yang mengimplementasikan Iterableantarmuka .

Juga, jika sisi kanan for (:)idiom adalah arraybukan Iterableobjek, kode internal menggunakan penghitung indeks int dan memeriksa array.lengthsebaliknya. Lihat Spesifikasi Bahasa Jawa .

tidak doa
sumber
14
Saya baru saja menemukan memanggil while-loop seperti while (someList.hasMoreElements ()) {// do something}} - membuat saya dekat dengan rahmat pengkodean yang saya harap akan temukan ketika saya mencari pertanyaan ini.
James T Snell
6
Juga lihat docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html yang menjelaskan loop foreach (saat diperkenalkan)
PhoneixS
1
untuk pengembang studio android: import java.util.Iterator;danimport java.lang.Iterable;
dsdsdsdsd
Dengan frustrasi, java.util.Iteratortidak diterapkan Iterablesehingga Anda tidak bisa for(String s : (Iterator<String>)foo). Saya mengerti mengapa hal ini, tetapi yang menjengkelkan.
Christopher Schultz
499

Konstruk untuk masing-masing juga berlaku untuk array. misalnya

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

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

yang pada dasarnya setara dengan

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

Jadi, ringkasan keseluruhan:
[nsayer] Berikut ini adalah bentuk yang lebih panjang dari apa yang terjadi:

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

Perhatikan bahwa jika Anda perlu menggunakan i.remove (); di loop Anda, atau mengakses iterator aktual dengan cara tertentu, Anda tidak dapat menggunakan idiom for (:), karena Iterator yang sebenarnya hanya disimpulkan.

[Denis Bueno]

Ini tersirat oleh jawaban nsayer, tetapi perlu dicatat bahwa sintaks OP untuk (..) akan bekerja ketika "someList" adalah apa pun yang mengimplementasikan java.lang. Dapat diubah - tidak harus berupa daftar, atau koleksi dari java.util. Bahkan tipe Anda sendiri, oleh karena itu, dapat digunakan dengan sintaks ini.

Mikezx6r
sumber
161

The foreachLoop , ditambahkan dalam Java 5 (juga disebut "disempurnakan untuk loop"), setara dengan menggunakan java.util.Iteratorsintaksis gula --Itu untuk hal yang sama. Karena itu, ketika membaca setiap elemen, satu per satu dan berurutan, a foreachharus selalu dipilih daripada iterator, karena lebih nyaman dan ringkas.

untuk setiap

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

Ada situasi di mana Anda harus menggunakan secara Iteratorlangsung. Misalnya, mencoba menghapus elemen saat menggunakan foreachkaleng (akan?) Menghasilkan a ConcurrentModificationException.

foreachvs for.: Perbedaan mendasar

Satu-satunya perbedaan praktis antara fordan foreachadalah, dalam hal objek yang dapat diindeks, Anda tidak memiliki akses ke indeks. Contoh ketika forloop dasar diperlukan:

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

Meskipun Anda bisa secara manual membuat indeks terpisah dengan variabel foreach,

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

itu tidak disarankan, karena variabel-lingkup tidak ideal, dan forloop dasar hanyalah format standar dan yang diharapkan untuk kasus penggunaan ini.

foreachvs for.: Kinerja

Saat mengakses koleksi, a foreachsecara signifikan lebih cepat dari forakses larik loop dasar . Ketika mengakses array, namun - setidaknya dengan array primitif dan wrapper - akses melalui indeks secara dramatis lebih cepat.

Mengatur waktu perbedaan antara akses iterator dan indeks untuk array int-primitif

Indeks adalah 23- 40 persen lebih cepat dari iterator ketika mengakses intatau Integerarray. Berikut ini adalah output dari kelas pengujian di bagian bawah posting ini, yang merangkum angka-angka dalam array elemen-primitif 100-elemen (A adalah iterator, B adalah 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)

Saya juga menjalankan ini untuk Integerarray, dan indeks masih merupakan pemenang yang jelas, tetapi hanya antara 18 dan 25 persen lebih cepat.

Untuk koleksi, iterator lebih cepat dari indeks

Untuk Listof IntegersNamun, iterator adalah pemenang yang jelas. Cukup ubah int-array di kelas uji menjadi:

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

Dan buat perubahan yang diperlukan pada fungsi uji ( int[]ke List<Integer>, lengthke size(), dll.):

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

Dalam satu tes mereka hampir setara, tetapi dengan koleksi, iterator menang.

* Posting ini didasarkan pada dua jawaban yang saya tulis di Stack Overflow:

Beberapa informasi lebih lanjut: Mana yang lebih efisien, untuk setiap loop, atau iterator?

Kelas pengujian lengkap

Saya membuat kelas perbandingan-waktu-dibutuhkan-untuk-melakukan-dua-hal ini setelah membaca pertanyaan ini di 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;/programming/180158/how-do-i-time-a-methods-execution-in-java&quot;&gt;/programming/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

}
Aliteralmind
sumber
4
Jawaban ini sekarang adalah posting blog dan dibuat dari dua jawaban terkait yang saya tulis: di sini dan di sini . Ini juga termasuk kelas yang berguna secara umum untuk membandingkan kecepatan dua fungsi (di bagian bawah).
aliteralmind
1
Hanya satu komentar kecil di sini, Anda tidak boleh secara kategoris menyatakan bahwa untuk (:) sintaks selalu lebih baik untuk mengakses koleksi; jika Anda menggunakan daftar array, loop for (:) akan sekitar 2 x lebih lambat daripada menggunakan for (int i = 0, len = arrayList.size (); i <len; i ++). Saya pikir Anda menyebutkan bahwa di tautan [tautan] ( stackoverflow.com/questions/2113216/... ), tetapi penting untuk menyoroti itu ...
Leo
@ Leo Ini poin bagus. ArrayList adalah Koleksi, tetapi didukung oleh array, itulah sebabnya normal untuk lebih baik untuk itu.
aliteralmind
Saya membayangkan yang for(int value : int_array) {/* loop content */}paling lambat dalam tes Anda karena secara sintaksis setara dengan for(int i = 0; i < int_array.length; i++) {int value = int_array[i]; /* loop content */}, yang tidak sebanding dengan tes Anda.
daiscog
(Omong-omong, saya tidak mengatakan tes Anda tidak valid, tetapi mungkin perlu dicatat alasan di balik perbedaan sehingga orang dapat memilih apa yang tepat untuk skenario khusus mereka. Jika mereka melakukan a int value = int_array[i];pada awal untuk loop, maka mereka mungkin juga menggunakan foreach. Kecuali mereka membutuhkan akses ke indeks juga, untuk beberapa alasan. Singkatnya, itu semua tergantung pada konteks.)
daiscog
129

Berikut ini adalah jawaban yang tidak mengasumsikan pengetahuan tentang Java Iterators. Ini kurang tepat, tetapi berguna untuk pendidikan.

Saat pemrograman kita sering menulis kode yang terlihat seperti berikut:

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]
}

Sintaks foreach memungkinkan pola umum ini ditulis dalam cara yang lebih alami dan kurang berisik secara sintaksis.

for(char grade : grades) {   // foreach grade in grades
    System.out.print(grade); // print that grade
}

Selain itu sintaks ini berlaku untuk objek seperti Daftar atau Set yang tidak mendukung pengindeksan array, tetapi yang mengimplementasikan antarmuka Java Iterable.

MRocklin
sumber
40

Untuk-setiap loop di Jawa menggunakan mekanisme iterator yang mendasarinya. Jadi identik dengan yang berikut:

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

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

Dalam fitur Java 8 Anda dapat menggunakan ini:

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

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

Keluaran

First
Second
Third
Jrovalle
sumber
7
informasi acak ini bahkan tidak menjawab pertanyaan dari jarak jauh
Tim
25

Ini tersirat oleh jawaban nsayer, tetapi perlu dicatat bahwa sintaks OP untuk (..) akan bekerja ketika "someList" adalah apa pun yang mengimplementasikan java.lang. Dapat diubah - tidak harus berupa daftar, atau koleksi dari java.util. Bahkan tipe Anda sendiri, oleh karena itu, dapat digunakan dengan sintaks ini.

EfForEffort
sumber
1
fd benar - kode internal ketika sisi kanan idiom for (:) menggunakan int dan array.length alih-alih mengambil Iterator. forums.sun.com/thread.jspa?messageID=2743233
nsayer
24

Sebagaimana didefinisikan dalam JLS untuk-setiap loop dapat memiliki dua bentuk:

  1. Jika jenis Ekspresi adalah subtipe dari Iterablemaka terjemahan adalah sebagai:

    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. Jika Ekspresi tentu memiliki tipe array T[]maka:

    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 telah memperkenalkan stream yang berkinerja lebih baik secara umum. Kita dapat menggunakannya sebagai:

someList.stream().forEach(System.out::println);
Arrays.stream(someArray).forEach(System.out::println);
akhil_mittal
sumber
2
Jawaban yang paling relevan dan akurat. Enchansed for memiliki dua terjemahan.
Zarial
23

Sintaks loop foreach adalah:

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

Contoh:

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

Keluaran:

Java
Coffe
Is
Cool

PERINGATAN: Anda dapat mengakses elemen array dengan loop foreach, tetapi Anda TIDAK dapat menginisialisasi mereka. Gunakan forloop asli untuk itu.

PERINGATAN: Anda harus mencocokkan jenis array dengan objek lain.

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

Jika Anda ingin mengedit elemen, gunakan forloop asli seperti ini:

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

Sekarang jika kita membuang s ke konsol, kita mendapatkan:

hello
2 is cool
hello
hello
Nama Pribadi
sumber
21

Konstruk loop Java "untuk-masing-masing" akan memungkinkan iterasi atas dua jenis objek:

  • T[] (array jenis apa pun)
  • java.lang.Iterable<T>

The Iterable<T>antarmuka hanya memiliki satu metode: Iterator<T> iterator(). Ini berfungsi pada objek bertipe Collection<T>karena Collection<T>antarmuka memanjang Iterable<T>.

Ryan Delucchi
sumber
16

Konsep loop foreach seperti yang disebutkan dalam Wikipedia disorot di bawah ini:

Tidak seperti yang lain untuk konstruksi loop, bagaimanapun, foreach loop biasanya tidak memiliki counter eksplisit : mereka pada dasarnya mengatakan "lakukan ini untuk semua yang ada di set ini", daripada "lakukan ini x kali". Ini menghindari potensi kesalahan satu per satu dan membuat kode lebih mudah dibaca.

Jadi konsep loop foreach menjelaskan bahwa loop tidak menggunakan penghitung eksplisit yang berarti bahwa tidak perlu menggunakan indeks untuk melintasi dalam daftar sehingga menghemat pengguna dari kesalahan satu per satu. Untuk menjelaskan konsep umum dari kesalahan satu-per-satu ini, mari kita ambil contoh loop untuk melintasi dalam daftar menggunakan indeks.

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

}

Tetapi anggaplah jika daftar dimulai dengan indeks 1 maka loop ini akan melempar pengecualian karena tidak akan menemukan elemen pada indeks 0 dan kesalahan ini disebut kesalahan satu-per-satu. Jadi untuk menghindari kesalahan off-by-one ini digunakan konsep foreach loop. Mungkin ada keuntungan lain juga, tapi ini yang saya pikir adalah konsep utama dan keuntungan menggunakan foreach loop.

satuKesadaran
sumber
13

Di Java 8, mereka memperkenalkan forach. Menggunakan Daftar itu, Peta dapat dilingkarkan.

Lingkari Daftar menggunakan untuk masing-masing

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

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

atau

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

Lingkari Peta menggunakan untuk masing-masing

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

atau

mapList.forEach((key,value)->{
    System.out.println("Key : " + key + " Value : " + value);
});
vivekkurien
sumber
12
for (Iterator<String> itr = someList.iterator(); itr.hasNext(); ) {
   String item = itr.next();
   System.out.println(item);
}
Roger Lindsjö
sumber
11

Menggunakan versi Java yang lebih lama termasuk Java 7Anda dapat menggunakan foreachloop sebagai berikut.

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

Mengikuti adalah cara terbaru menggunakan foreachloop inJava 8

(loop Daftar dengan forEachekspresi + lambda atau referensi metode)

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

Untuk info lebih lanjut lihat tautan ini.

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

Dulith De Costa
sumber
10

Inilah ekspresi yang setara.

for(Iterator<String> sit = someList.iterator(); sit.hasNext(); ) {
    System.out.println(sit.next());
}
Gulungan
sumber
10

Perhatikan juga bahwa menggunakan metode "foreach" dalam pertanyaan asli memang memiliki beberapa keterbatasan, seperti tidak dapat menghapus item dari daftar selama iterasi.

For-loop baru lebih mudah dibaca dan menghilangkan kebutuhan untuk iterator yang terpisah, tetapi hanya benar-benar dapat digunakan dalam pass iterasi read-only.

billjamesdev
sumber
1
Dalam kasus itu, penggunaan removeIfmungkin alat yang tepat
ncmathsadist
9

Alternatif untuk forEach untuk menghindari "untuk masing-masing" Anda:

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

Varian 1 (biasa):

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

Varian 2 (eksekusi paralel (lebih cepat)):

someList.parallelStream().forEach(listItem -> {
    System.out.println(listItem);
});
Alexander Drobyshevsky
sumber
2
Seharusnya menyebutkan bahwa itu ditambahkan di Jawa 1.8
TheLibrarian
Kami tidak dapat 100% yakin bahwa utas yang sama digunakan. Saya suka menggunakan for(formulir jika saya ingin memastikan utas yang sama digunakan. Saya suka menggunakan stream-form jika saya ingin mengizinkan eksekusi multithreaded.
Muram
8

Ini menambah keindahan kode Anda dengan menghapus semua kekacauan perulangan dasar. Ini memberikan tampilan bersih ke kode Anda, dibenarkan di bawah ini.

forLingkaran normal :

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

Gunakan untuk masing-masing:

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

untuk-masing-masing adalah konstruksi atas koleksi yang mengimplementasikan Iterator . Ingat itu, koleksi Anda harus menerapkan Iterator ; jika tidak, Anda tidak dapat menggunakannya dengan masing-masing.

Baris berikut dibaca sebagai " untuk setiap t TimerTask dalam daftar. "

for (TimerTask t : list)

Ada sedikit kemungkinan kesalahan dalam kasus untuk masing-masing. Anda tidak perlu khawatir tentang menginisialisasi iterator atau menginisialisasi penghitung lingkaran dan menghentikannya (di mana ada ruang untuk kesalahan).

Manohar
sumber
8

Sebelum ke Java 8, Anda harus menggunakan yang berikut ini:

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

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

Namun, dengan diperkenalkannya Streams di Java 8 Anda dapat melakukan hal yang sama dalam sintaks yang jauh lebih sedikit. Misalnya, untuk Anda, someListAnda dapat melakukan:

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

Anda dapat menemukan lebih banyak tentang stream di sini .

stackFan
sumber
The foreach loop, added in Java 5 (also called the "enhanced for loop"), is equivalent to using a java.util.Iterator
Alex78191
7

Akan terlihat seperti ini. Sangat kekar.

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

Ada Langgan baik pada setiap dalam dokumentasi Sun .

Pete
sumber
6

Seperti yang dikatakan oleh begitu banyak jawaban yang baik, suatu objek harus mengimplementasikan Iterable interfacejika ia ingin menggunakan afor-each loop.

Saya akan memposting contoh sederhana dan mencoba menjelaskan dengan cara yang berbeda cara for-eachkerja loop.

Contoh for-eachloop:

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

Kemudian, jika kita gunakan javapuntuk mendekompilasi kelas ini, kita akan mendapatkan sampel bytecode ini:

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;

Seperti yang dapat kita lihat dari baris terakhir sampel, kompiler akan secara otomatis mengonversi penggunaan for-eachkata kunci menjadi penggunaan Iteratorpada waktu kompilasi. Itu mungkin menjelaskan mengapa objek, yang tidak mengimplementasikan Iterable interface, akan melempar Exceptionketika mencoba menggunakan for-eachloop.

L Joey
sumber
6

The Java untuk setiap loop (alias ditingkatkan untuk loop) adalah versi sederhana dari untuk loop. Keuntungannya adalah bahwa ada lebih sedikit kode untuk ditulis dan lebih sedikit variabel untuk dikelola. Kelemahannya adalah bahwa Anda tidak memiliki kendali atas nilai langkah dan tidak ada akses ke indeks loop di dalam tubuh loop.

Mereka paling baik digunakan ketika nilai langkah adalah kenaikan sederhana 1 dan ketika Anda hanya perlu akses ke elemen loop saat ini. Misalnya, jika Anda perlu mengulang setiap elemen dalam array atau Koleksi tanpa mengintip ke depan atau di belakang elemen saat ini.

Tidak ada inisialisasi loop, tidak ada kondisi boolean dan nilai langkah implisit dan merupakan kenaikan sederhana. Inilah mengapa mereka dianggap jauh lebih sederhana daripada yang biasa untuk loop.

Ditingkatkan untuk loop, ikuti urutan eksekusi ini:

1) loop body

2) ulangi dari langkah 1 sampai seluruh larik atau koleksi telah dilintasi

Contoh - Bilangan Integer

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

Variabel currentValue memegang nilai saat ini dilingkarkan di dalam array intArray. Perhatikan bahwa tidak ada nilai langkah eksplisit - ini selalu merupakan kenaikan sebesar 1.

Usus besar dapat dianggap berarti "dalam". Jadi deklarasi loop yang disempurnakan menyatakan: loop over intArray dan menyimpan nilai int array saat ini dalam variabel currentValue.

Keluaran:

1
3
5
7
9

Contoh - String Array

Kita dapat menggunakan untuk-setiap loop untuk beralih di atas array string. Deklarasi loop menyatakan: loop over myStrings String array dan menyimpan nilai String saat ini dalam variabel currentString.

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

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

Keluaran:

alpha
beta
gamma
delta

Contoh - Daftar

Enhanced for loop juga dapat digunakan untuk beralih ke java.util.List sebagai berikut:

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

Deklarasi loop menyatakan: loop over myList List of Strings dan menyimpan nilai Daftar saat ini di variabel currentItem.

Keluaran:

alpha
beta
gamma
delta

Contoh - Set

Enhanced for loop juga dapat digunakan untuk beralih ke java.util.Set sebagai berikut:

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

Deklarasi loop menyatakan: loop over mySet Set of Strings dan menyimpan nilai Set saat ini dalam variabel currentItem. Perhatikan bahwa karena ini adalah Set, nilai-nilai String duplikat tidak disimpan.

Keluaran:

alpha
delta
beta
gamma

Sumber: Loops in Java - Ultimate Guide

gomisha
sumber
4
public static Boolean Add_Tag(int totalsize)
{ List<String> fullst = new ArrayList<String>();
            for(int k=0;k<totalsize;k++)
            {
              fullst.addAll();
            }
}
Santhosh Rajkumar
sumber
3

Java untuk-setiap idiom hanya dapat diterapkan pada array atau objek bertipe * Iterable . Ungkapan ini tersirat karena benar-benar didukung oleh Iterator. Iterator diprogram oleh programmer dan sering menggunakan indeks integer atau node (tergantung pada struktur data) untuk melacak posisinya. Di atas kertas itu lebih lambat dari pada loop biasa, paling tidak untuk struktur "linier" seperti array dan Daftar tetapi memberikan abstraksi yang lebih besar.

TheArchon
sumber
-1: ini cara yang kurang dapat dibaca (umumnya): bahkan contoh Anda sendiri (yang pertama) salah, karena ia meninggalkan elemen pertama dalam array.
Ondrej Skopek
2

Ini terlihat gila tapi hei itu berhasil

List<String> someList = new ArrayList<>(); //has content
someList.forEach(System.out::println);

Ini bekerja. Sihir

Rei Brown
sumber
1
Ini membutuhkan Java 1.8 +
BARNI
2
bahkan tidak menjawab pertanyaan dari jarak jauh
Tim
2

Seperti banyak jawaban lain menyatakan dengan benar, for each loopitu hanya gula sintaksis di atas yang sama for loopdan kompiler menerjemahkannya ke yang sama untuk loop.

javac (open jdk) memiliki saklar -XD-printflat, yang menghasilkan file java dengan semua gula sintaksis dihapus. perintah lengkapnya terlihat seperti ini

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

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

Jadi mari kita hapus gula sintaksis

Untuk menjawab pertanyaan ini, saya membuat file dan menulis dua versi for each, satu dengan arraydan yang lain dengan a list. javafile saya terlihat seperti ini.

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

Ketika saya compiledfile ini dengan switch di atas, saya mendapat output berikut.

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

Anda dapat melihat bahwa bersama dengan gula sintaksis lainnya (Autoboxing) untuk setiap loop diubah menjadi loop sederhana.

perkasaWOZ
sumber
-2
List<Item> Items = obj.getItems();
for(Item item:Items)
             {
                System.out.println(item); 
             }

Iterasikan semua objek dalam tabel Item.

shubhranshu
sumber
1
Pengguna belum meminta sintaks
pradipgarala