Sobes.tech
Middle

Kolleksiyani aylanib o'tishda ConcurrentModificationException xatosidan qanday qochish mumkin?

sobes.tech AI

AIdan javob

Kolleksiyani aylanayotganda ConcurrentModificationException xatosidan qochish uchun quyidagi yondashuvlardan foydalanish mumkin:

  1. Xavfsiz oqim kolleksiyalaridan foydalanish: java.util.concurrent standart kolleksiyalarning xavfsiz alternativlarini taqdim etadi. Masalan:

    • CopyOnWriteArrayList ArrayList o'rniga
    • CopyOnWriteArraySet HashSet o'rniga
    • ConcurrentHashMap HashMap o'rniga
    // CopyOnWriteArrayList bilan misol
    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");
    
            // Iterator `ConcurrentModificationException`ni chiqarmaydi
            Iterator<String> iterator = list.iterator();
            while (iterator.hasNext()) {
                String element = iterator.next();
                System.out.println(element);
                // Kolleksiyani o'zgartirish xavfsiz
                if (element.equals("B")) {
                    list.remove(element);
                }
            }
            System.out.println("Oxirgi ro'yxat: " + list);
        }
    }
    
  2. Kolleksiyani bloklash: synchronized yoki java.util.concurrent.locks yordamida kolleksiyaga kirishni sinxronlashtirish.

    // Synchronized blok bilan misol
    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) { // Kolleksiyani bloklash
               Iterator<String> iterator = list.iterator();
               while (iterator.hasNext()) {
                   String element = iterator.next();
                   System.out.println(element);
                   // Bu yerda kolleksiyani o'zgartirish mumkin emas, agar boshqa oqim ham kirsa
               }
           }
           // Kolleksiyani sinxronizatsiya qilinmagan holda o'zgartirish
           // yoki boshqa oqim bilan bajarilsa, `ConcurrentModificationException` yuzaga kelishi mumkin
       }
    }
    
  3. Iterator yordamida elementlarni o'chirish: Agar o'chirish kerak bo'lsa, remove() metodidan foydalaning (agar kolleksiya qo'llab-quvvatlasa).

    // Iterator.remove() bilan o'chirish misoli
    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);
                // Iterator yordamida elementni o'chirish xavfsiz
                if (element.equals("B")) {
                    iterator.remove();
                }
            }
            System.out.println("Oxirgi ro'yxat: " + list);
        }
    }
    
  4. Kolleksiyaning nusxasini aylaning: Kolleksiyaning nusxasini yarating va uni aylaning. Asl kolleksiyadagi o'zgarishlar nusxaga ta'sir qilmaydi.

    // Nusxa bilan aylaning misoli
    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");
    
            // Aylanadigan nusxa yaratamiz
            List<String> copyList = new ArrayList<>(list);
    
            for (String element : copyList) {
                System.out.println(element);
                // Asl kolleksiyani o'zgartirish mumkin, nusxaga ta'sir qilmaydi
                if (element.equals("B")) {
                    list.remove(element);
                }
            }
            System.out.println("Oxirgi ro'yxat: " + list);
        }
    }
    

Yondashuv tanlash aniq talablar va shartlarga bog'liq: kolleksiyani aylanayotganda o'zgartirish kerakmi, ishlash tezligi muhimmi, va kod ko'p oqimli muhitda ishlayaptimi. CopyOnWriteArrayList/CopyOnWriteArraySet ko'p o'qish va kam yozish bo'lsa mos keladi. Bloklash kamroq o'zgarishlar bo'lsa, lekin CopyOnWrite ga qaraganda ko'proq ishlatilishi mumkin. Iterator.remove() yoki nusxa aylanadigan usul faqat bitta aylanma yoki oqimda o'zgarishlar bo'lsa qo'llanadi.