for (String s : list) {
// s'i kullanan veya kullanmayan işlemler...
}
Bu örnekte type safety'de sağlanmış oluyor. Generics o biçim destekleniyor yani:). Bir diğer örnekte array'ler için. Örneğin elinizde A sınıfı tipinde "arr" isminde bir diziniz olsun, bu dizi üzerinde aşağıdaki şekilde dolaşabilirsiniz:
for (A item : arr) {
// item ile bir işlem yap...
}
Iterator java'da bildim bileli olan bir şey, Iterator ile Collection nesnesinin elemanları üzerinde dolaşabilir ve işlemler yapabilirsiniz ve o collection nesnesi de bu değişikliklerden etkilenir. Örneğin; içinde String nesneleri barındıran "mySet" isminde bir HashSet nesneniz bulunmaktadır. Bu set üzerinde aşağıdaki şekilde dolaşabilirsiniz.
Iterator
while ( iter.hasNext() ) {
String s = iter.next();
// işlemlere devam et...
}
Gördüğünüz gibi "for each" yapısı Iterator'dan daha basit ve anlaşılır. Ancak Iterator'un pabucunun dama kaldırılmayacağını dün anladım.
İçinde oluşturduğum sınıf tipinde nesneler barındıran bir List üzerinde bir kaç işlem yapacaktım. Bu işlem de list elemanları üzerinde sırayla ilerleyip her elemanı bir koşuldan geçirip eğer koşul sağlanırsa o elemanı listeden kaldırmaktı. Bu işlemi for each ile aşağıdaki gibi yapmıştım:
List
for (MyClass m : list ) {
if ( condition )
list.remove(m);
}
Bu kodu çalıştırdığımda java.util.ConcurrentModificationException aldım. Daha sonra aynı işlemi Iterator ile yaptım.
List
Iterator
while (iter.hasNext()) {
MyClass m = iter.next();
if ( condition )
iter.remove();
}
Bu kodda ise hata almadım. Nedeni kesin olarak bilmemekle beraber bildiğim kadarıyla Iterator bir Collection nesnesi içindeki elemanlar üzerinde pointer mantığıyla çalışıyor. For each'de ise böyle bir yapı yok, yani bir array gibi çalışıyor. Bu nedenle "for each" ile list üzerinde dolaşırken aynı anda bir nesneyi listeden kaldırmak istediğinizde nesnelerin indexleri değiştiğinden dolayı bu hatayı veriyor olabilir. Iterator ise kaldırılacak elemana point ettiğinden elemanı listeden kaldırıyor ve pointer'ını yeni nesne üzerinde konumlandırıyor, bir linked list mantığı. Siz ne dersiniz?
9 yorum:
Kullanım olarak foreach yaklaşımı bir liste uzerinde gezinmek amacıyla ortaya çıkmıştır. bir operasyon yapılmaması gerektiğini zaten belirtiyor kitap veya tutoriallar.
Ben de tecrübe ettim:)
ya iki defa uzunca yorum yazdim cikmadi..
Yorumları ben yayınlıyorum. Bunu da spam yorumlar oluyor, onların önüne geçmek için yaptım. İsterseniz bir defa daha yazın...
http://javaadami.blogspot.com/2007/09/enhanced-for-loop-and.html
Teşekkürler bu doyurucu bilgi için...
Listenin index'ini temel alan hiç bir loop'ta değişiklik yapmamak gereklidir. ConcurrentModificationException vermezse bile indexler karışacaktır. Bu sadece Foreach'e özgü değil. Yani herhangi bir döngüde eğer döngü temelini oluşturan bir liste ise ve bu listenin operasyona direk olarak tabi tutulması gerekiyorsa Exception almamak için while döngüsü kullanılabilir. Ama indexleme bozulacaktır. Bu yüzden dikkatli olmak gerekir.
ben döngünün içinde remove yapmamama rağmen hata aldım? acaba nedendir?
Detaylı bilgi A.A.A'nın verdiği linkte bulunmaktadır kanımca...
Yorum Gönder