Bir koleksiyon üzerinde gezinirken ConcurrentModificationException istisnasını nasıl önlersiniz?
sobes.tech yapay zeka
AI'dan gelen yanıt
Bir koleksiyon üzerinde gezinirken ConcurrentModificationException hatasını önlemek için aşağıdaki yaklaşımları kullanabilirsiniz:
-
İş parçacığı güvenli koleksiyonlar kullanmak:
java.util.concurrent, standart koleksiyonlara göre iş parçacığı güvenli alternatifler sunar. Örneğin:CopyOnWriteArrayListyerineArrayListCopyOnWriteArraySetyerineHashSetConcurrentHashMapyerineHashMap
// CopyOnWriteArrayList ile örnek import java.util.concurrent.CopyOnWriteArrayList; import java.util.Iterator; public class ConcurrentCollectionExample { public static void main(String[] args) { CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); list.add("A"); list.add("B"); list.add("C"); // İteratör, ConcurrentModificationException fırlatmaz Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String element = iterator.next(); System.out.println(element); // Koleksiyonu değiştirmek güvenlidir if (element.equals("B")) { list.remove(element); } } System.out.println("Final liste: " + list); } } -
Koleksiyonu kilitlemek:
synchronizedveyajava.util.concurrent.lockskullanarak koleksiyona erişimi senkronize edin.// Senkronize blok ile örnek import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class SynchronizedCollectionExample { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); synchronized (list) { // Koleksiyonu erişim için kilitler Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String element = iterator.next(); System.out.println(element); // Başka bir iş parçacığı bu blok içinde koleksiyonu değiştiremez } } // Koleksiyon, başka bir iş parçacığında veya blok dışında değiştirilebilir // ve yine de paralel iterasyonda ConcurrentModificationException oluşabilir } } -
İteratör kullanarak öğeleri kaldırmak: Öğeleri iterasyon sırasında kaldırmanız gerekiyorsa,
remove()metodunu kullanın (koleksiyon bunu destekliyorsa).// Iterator.remove() kullanımıyla örnek import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class IteratorRemoveExample { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String element = iterator.next(); System.out.println(element); // Güvenli bir şekilde öğeyi kaldır if (element.equals("B")) { iterator.remove(); } } System.out.println("Final liste: " + list); } } -
Koleksiyonun bir kopyasını dolaşmak: Koleksiyonun bir kopyasını oluşturun ve onu dolaşın. Orijinal koleksiyonda yapılan değişiklikler, kopya üzerinde yapılan iterasyonu etkilemez.
// Kopya üzerinde dolaşma örneği import java.util.ArrayList; import java.util.List; public class CopyIterationExample { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); // Dolaşmak için kopya oluştur List<String> copyList = new ArrayList<>(list); for (String element : copyList) { System.out.println(element); // Orijinal koleksiyonu, kopya üzerinde dolaşırken değiştirebiliriz if (element.equals("B")) { list.remove(element); } } System.out.println("Final liste: " + list); } }
Yaklaşım seçimi, belirli gereksinimlere bağlıdır: koleksiyonu iterasyon sırasında değiştirmek gerekiyor mu, performans ne kadar önemli ve kod çok iş parçacıklı ortamda mı çalışıyor. CopyOnWriteArrayList/CopyOnWriteArraySet, okuma işlemleri yazma işlemlerinden çok daha fazla ise uygundur. Kilitleme, değişiklikler daha seyrek ise ve CopyOnWrite'a göre daha sık olabiliyorsa uygundur. Iterator.remove() veya kopya dolaşımı, değişikliklerin yalnızca bir iterasyon veya iş parçacığında gerçekleştiği durumlarda kullanışlıdır.