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

  • katherine gomez

    katherine go

    1 Aralık 2011
  • metallmanutza13

    metallmanutz

    13 NİSAN 2007
  • williamfitzsimmons

    williamfitzs

    14 Mart 2008