Menu

Java for-each Döngüsü: Söz Dizimi, Örnekler ve Tuzaklar

Java for-each (gelişmiş for) döngüsü anlatılıyor: diziler ve koleksiyonlar üzerinde temiz yineleme, ne zaman kullanılacağı ve herkesi yanıltan değiştirme tuzağı.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

İndeks Yalnızca Ayak Bağı Olduğunda

Sayaçlı bir for döngüsü sana bir sayaç, bir koşul ve bir güncelleme adımı verir. Ama çoğu zaman aslında bir elemanın konumu umurunda değildir; sadece her birine sırayla, baştan sona bir şeyler yapmak istersin. Bunun için bir indeks yönetmek boş iştir ve birer fazla/eksik (off-by-one) hataları tam da buraya sızar.

for-each döngüsü (Java'nın ona verdiği ad gelişmiş for) sayacı tamamen kaldırır. Bir değişken adlandırır, onu bir koleksiyona yöneltirsin ve döngü sana her elemanı sırayla verir.

Temel Söz Dizimi

Şekli for (Tip eleman : koleksiyon) biçimindedir. İki noktayı "içindeki" kelimesi gibi oku:

i yok, scores.length yok, scores[i] yok. Her geçişte score zaten bir sonraki elemandır. Döngü her eleman için bir kez çalışır ve eleman kalmadığında otomatik olarak durur; sonu geçemez veya bir eleman erken başlayamazsın.

Bir Liste Üzerinde Dönme

Aynı döngü, List, Set ve diğer koleksiyon türlerini de kapsayan yinelenebilir her şeyle çalışır. Eleman tipi değişken adından önce gelir:

langs'in bir diziyle mi, bağlı listeyle mi yoksa başka bir şeyle mi desteklendiğini bilmen veya umursaman gerekmediğine dikkat et; for-each hepsinde aynı şekilde çalışır. Asıl gücü budur: her koleksiyon için tek bir okunabilir söz dizimi.

var Sana Tip Adını Yazma Zahmetini Kaldırır

Eleman tipi uzun veya bariz ise, var derleyicinin onu çıkarsamasını sağlar, böylece kendini tekrarlamazsın:

var olmadan o döngü değişkeni ağız dolusu Map.Entry<String, Integer> olurdu. var onu okunabilir tutar ve tip yine de derleme zamanında tamamen denetlenir; bu, gevşek, dinamik bir tip değildir.

Değiştirme Tuzağı

İşte herkesi yakalayan kural: bir for-each döngüsü bir koleksiyonu dolaşırken ona eleman ekleyemez veya çıkaramazsın. Bunu yapmak bir ConcurrentModificationException fırlatır:

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

for (String item : items) {
    if (item.equals("b")) {
        items.remove(item);   // ConcurrentModificationException fırlatır
    }
}

Döngü, listenin altından değiştiğini fark eder ve elemanları sessizce atlamak veya tekrarlamak yerine durur. Güvenle silmek için, döngünün haberdar olduğu bir remove() metoduna sahip açık bir Iterator'a in:

Sık kullanılan bir kısayol, aynı işi tek satırda yapan items.removeIf(item -> item.equals("b"))tir.

Yalnızca Okuma, Yeniden Atama Yok

Bir başka ince sınır: döngü değişkenine atama yapmak yalnızca yerel kopyayı değiştirir, koleksiyonu değil. Bu, döngü değişkeninin canlı bir referans olduğu dillerden gelenleri şaşırtır:

Diziye geri yazman gerekiyorsa indekse ihtiyacın var ve bu da klasik sayaçlı for döngüsü demektir: for (int i = 0; i < nums.length; i++) nums[i] = nums[i] * 10;. Nesne elemanları için, değişkenin işaret ettiği nesneyi (örneğin bir setter çağırarak) değiştirebilirsin, ama onu koleksiyondaki yerinde başkasıyla değiştiremezsin.

break ve continue Hâlâ Çalışır

Bir for-each gerçek bir döngüdür, bu yüzden break ve continue her yerdeki gibi davranır: break döngüden çıkar, continue bir sonraki elemana atlar:

Bu keep ve ardından keep yazdırır: "skip"i atlar ve "never"a ulaşmadan "stop"ta durur. Yani her elemanı ziyaret etmeye mahkûm değilsin; sadece daha temiz kod karşılığında indeksten vazgeçersin.

Sonraki: Diziler

Artık dizileri gerçekte ne olduklarına takılmadan birkaç kez dolaştın: o .length alanına sahip sabit boyutlu, indeksli kaplar. Sonraki sayfa başa döner ve dizileri gerektiği gibi ele alır: onları nasıl bildireceğin, başladıkları varsayılan değerler ve sabit boyutlarının büyüyebilen bir ArrayList'ten nasıl farklı olduğu.

Sıkça Sorulan Sorular

Java'da for-each döngüsü nedir?

Bir for-each döngüsü (gelişmiş for olarak da bilinir) bir dizinin veya koleksiyonun her elemanını sayaç olmadan dolaşır: for (Tip eleman : koleksiyon) { ... }. "Koleksiyondaki her eleman için" diye okuyun. Yalnızca her elemana ihtiyacın olduğunda ve indekse asla ihtiyacın olmadığında, sayaçlı bir for döngüsünden daha temizdir.

Java'da for döngüsü ile for-each döngüsü arasındaki fark nedir?

Klasik for döngüsü açık bir sayaç kullanır (for (int i = 0; i < arr.length; i++)), böylece indeksi ve yönü sen kontrol edersin. for-each döngüsü, for (Tip x : arr), indekssizdir: her elemanı sırayla ziyaret eder. Yalnızca okuma amaçlı, baştan sona geçişler için for-each kullan; indekse ihtiyacın olduğunda, elemanları atlamak istediğinde veya koleksiyonun yapısını değiştirmek istediğinde sayaçlı döngüyü kullan.

for-each döngüm neden ConcurrentModificationException fırlatıyor?

Çünkü koleksiyonu bir for-each ile yinelerken üzerinde add() veya remove() çağırdın. Döngü yapısal değişikliği algılar ve seni tanımsız davranıştan korumak için istisna fırlatır. Elemanları güvenle silmek için açık bir Iterator ve onun remove() metodunu kullan veya silinecek elemanları toplayıp döngüden sonra kaldır.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA