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
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.
JSON ilişkisel dizi için bir anahtar l...
Java tersten bir liste boyunca yinelem...
döngü numaralama üzerinde yineleme içi...
Nasıl bağlantılı liste bir döngü algıl...
Nasıl bir foreach döngü içinde ilk ve ...