Menu

for-each Loop Java: Sintaks, Contoh, dan Jebakannya

Penjelasan for-each loop (enhanced for) di Java: iterasi yang rapi pada array dan collection, kapan memakainya, dan jebakan mengubah collection yang sering menjebak semua orang.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Saat Index Justru Mengganggu

for loop dengan penghitung memberimu penghitung, kondisi, dan langkah pembaruan. Tetapi sering sekali kamu sebenarnya tidak peduli pada posisi sebuah elemen. Kamu hanya ingin melakukan sesuatu pada setiap elemen, berurutan, dari awal sampai akhir. Mengurus index untuk itu hanyalah pekerjaan tambahan, dan justru di situlah bug selisih satu (off-by-one) diam-diam masuk.

For-each loop (Java menyebutnya for versi enhanced) sama sekali tidak memakai penghitung. Kamu memberi nama sebuah variabel, mengarahkannya ke sebuah collection, dan loop menyerahkan setiap elemen secara bergantian.

Sintaks Dasar

Bentuknya for (Type element : collection). Baca titik duanya sebagai kata "di dalam":

Tidak ada i, tidak ada scores.length, tidak ada scores[i]. Di setiap putaran, score adalah elemen berikutnya. Loop berjalan sekali untuk setiap elemen dan berhenti otomatis saat elemennya habis: kamu tidak mungkin berjalan melewati ujung atau mulai satu elemen terlalu awal.

Perulangan pada List

Loop yang sama bekerja pada apa pun yang iterable, termasuk List, Set, dan tipe collection lainnya. Tipe elemennya ditulis sebelum nama variabel:

Perhatikan bahwa kamu tidak perlu tahu atau peduli apakah langs didukung oleh array, linked list, atau yang lainnya: for-each bekerja dengan cara yang sama pada semuanya. Itulah kekuatannya yang sebenarnya: satu sintaks yang mudah dibaca untuk setiap collection.

var Menghemat Penulisan Nama Tipe

Kalau tipe elemennya panjang atau sudah jelas, var membuat compiler menyimpulkannya sehingga kamu tidak perlu mengulang-ulang:

Tanpa var, variabel loop itu harus ditulis sepanjang Map.Entry<String, Integer>. var membuatnya tetap mudah dibaca, dan tipenya tetap diperiksa sepenuhnya saat kompilasi: ini bukan tipe dinamis yang longgar.

Jebakan Mengubah Collection

Inilah aturan yang menjebak semua orang: kamu tidak bisa menambah atau menghapus elemen dari sebuah collection saat for-each loop sedang menelusurinya. Kalau kamu melakukannya, Java melempar ConcurrentModificationException:

List<String> items = new ArrayList<>(List.of("a", "b", "c"));

for (String item : items) {
    if (item.equals("b")) {
        items.remove(item);   // throws ConcurrentModificationException
    }
}

Loop menyadari bahwa list-nya berubah di tengah jalan dan memilih berhenti daripada diam-diam melewatkan atau mengulang elemen. Untuk menghapus dengan aman, turunlah ke Iterator eksplisit, yang punya remove() yang dikenali oleh loop:

Jalan pintas yang umum adalah items.removeIf(item -> item.equals("b")), yang memakai lambda expression untuk melakukan hal yang sama dalam satu baris.

Hanya Membaca, Bukan Mengganti

Batasan halus lainnya: memberi nilai baru ke variabel loop hanya mengubah salinan lokalnya, bukan collection-nya. Ini mengejutkan orang yang datang dari bahasa yang variabel loop-nya berupa referensi langsung:

Kalau kamu perlu menulis kembali ke array, kamu butuh index-nya, dan itu berarti for loop klasik dengan penghitung: for (int i = 0; i < nums.length; i++) nums[i] = nums[i] * 10;. Untuk elemen berupa objek, kamu bisa mengubah objek yang ditunjuk variabel itu (misalnya dengan memanggil setter), tetapi kamu tidak bisa menggantinya di dalam collection.

break dan continue Tetap Berfungsi

For-each adalah loop sungguhan, jadi break dan continue berperilaku persis sama seperti di tempat lain: break keluar dari loop, continue melompat ke elemen berikutnya:

Ini mencetak keep lalu keep: ia melewati "skip" dan berhenti di "stop" sebelum sampai ke "never". Jadi kamu tidak terpaksa mengunjungi setiap elemen; kamu hanya melepas index sebagai ganti kode yang lebih rapi.

Berikutnya: Array

Kamu sudah beberapa kali menelusuri array tanpa membahas apa sebenarnya array itu: wadah berukuran tetap dan ber-index dengan field .length. Halaman berikutnya kembali ke awal dan membahas array dengan tuntas: cara mendeklarasikannya, nilai default awalnya, dan bagaimana ukurannya yang tetap berbeda dengan ArrayList yang bisa bertambah.

Pertanyaan yang sering diajukan

Apa itu for-each loop di Java?

For-each loop (disebut juga enhanced for) menelusuri setiap elemen array atau collection tanpa penghitung: for (Type item : collection) { ... }. Bacalah sebagai "untuk setiap item di collection". Cara ini lebih rapi daripada for loop dengan penghitung saat kamu hanya butuh setiap elemennya dan tidak pernah butuh index-nya.

Apa perbedaan for loop dan for-each loop di Java?

for loop klasik memakai penghitung eksplisit (for (int i = 0; i < arr.length; i++)), jadi kamu yang mengendalikan index dan arahnya. For-each loop, for (Type x : arr), tidak punya index: ia mengunjungi setiap elemen secara berurutan. Pakai for-each untuk penelusuran dari depan ke belakang yang hanya membaca data; pakai loop dengan penghitung saat kamu butuh index, ingin melewati elemen tertentu, atau mengubah struktur collection-nya.

Kenapa for-each loop saya melempar ConcurrentModificationException?

Karena kamu memanggil add() atau remove() pada collection saat sedang menelusurinya dengan for-each. Loop itu mendeteksi perubahan struktur lalu melempar exception untuk melindungimu dari perilaku yang tidak terdefinisi. Untuk menghapus elemen dengan aman, pakai Iterator secara eksplisit beserta method remove()-nya, atau kumpulkan item yang ingin dihapus lalu hapus setelah loop selesai.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai