SORU
21 EKİM 2008, Salı


Bir liste boyunca yineleme, döngü çıkarırken ConcurrentModificationException kaçınarak

Hepimiz bunu yapamazsın biliyorum:

for (Object i : l) {
    if (condition(i)) {
        l.remove(i);
    }
}

ConcurrentModificationException vb... Bu görünüşe göre bazen çalışıyor, ama her zaman değil. İşte bazı özel kod:

public static void main(String[] args) {
    Collection<Integer> l = new ArrayList<Integer>();

    for (int i=0; i < 10;   i) {
        l.add(new Integer(4));
        l.add(new Integer(5));
        l.add(new Integer(6));
    }

    for (Integer i : l) {
        if (i.intValue() == 5) {
            l.remove(i);
        }
    }

    System.out.println(l);
}

Bu, tabii ki, sonuçlar:

Exception in thread "main" java.util.ConcurrentModificationException

... hatta birden çok iş parçacığı olsa bunu yapıyor değil mi... Neyse.

Bu sorun için en iyi çözüm nedir? Nasıl bu özel durum üretiliyor olmadan döngü koleksiyonundan bir öğeyi kaldırabilir miyim?

Ayrıca bir keyfi Collection burada, ille güvenemezsin yani ArrayList, get kullanıyorum.

CEVAP
21 EKİM 2008, Salı


Iterator.remove() güvenlidir, bu gibi kullanabilirsiniz:

List<String> list = new ArrayList<>();

// This is a clever way to create the iterator and call iterator.hasNext() like
// you would do in a while-loop. It would be the same as doing:
//     Iterator<String> iterator = list.iterator();
//     while (iterator.hasNext()) {
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
    String string = iterator.next();
    if (string.isEmpty()) {
        // Remove the current element from the iterator and the list.
        iterator.remove();
    }
}

Iterator.remove yineleme sırasında bir toplama değiştirmek için tek güvenli yolu olduğunu unutmayın; bu davranış, eğer temel koleksiyonu yineleme işlemi sırasında herhangi bir şekilde değiştirilmiş ise belirsiz.

Kaynak:

http://docs.oracle.com/javase/tutorial/collections/interfaces/collection.html


Ve benzer şekilde, ListIterator varsa ve istiyorsanekleyinöğe Iterator#remove - kullanabilirsiniz aynı sebepten ListIterator#add kullanın; buna izin vermek için tasarlanmıştır.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Jose LviS el Bambino ( JLB )   LviSito

    Jose LviS el

    3 ŞUBAT 2008
  • ipsy

    ipsy

    1 EKİM 2012
  • TopDJMag TV

    TopDJMag TV

    29 Temmuz 2010