|
Java форум JavaTalks форум программистов
|
|
|
|
| Предыдущая тема :: Следующая тема |
| Автор |
Сообщение |
loz_a : 163 Новичок Откуда: Моршин
|
Июн 30, 2008 22:48 |
|
|
Есть до ужаса простая програмка....
| Код: |
import java.util.*;
/**
* @author Andriy Create a class, then make an initialized array of objects of
* your class. Fill a List from your array. Create a subset of your List
* using subList( ), and then remove this subset from your List using
* removeAll( ).
*/
public class Exercise22 {
private int i;
Exercise22(int i) {
this.i = i;
}
public String toString() {
return "Exercise22 " + i;
}
public static void printArray(List<Exercise22> list) {
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i).toString());
}
}
public static void main(String[] args) {
List<Exercise22> linkedlist = Collections
.synchronizedList(new LinkedList<Exercise22>());
for (int i = 0; i < 20; i++) {
linkedlist.add(new Exercise22(i));
}
printArray(linkedlist);
List<Exercise22> list = Collections.synchronizedList(linkedlist.subList(8, 16));
System.out.println();
printArray(list);
synchronized (linkedlist) {
linkedlist.removeAll(list);
}
printArray(linkedlist);
}
}
|
И ессть до ужаса назоиливое есключение, которое выскакивает в самый не подходящий момент...
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.SubList.checkForComodification(AbstractList.java:855)
at java.util.SubList.listIterator(AbstractList.java:785)
at java.util.AbstractList.listIterator(AbstractList.java:349)
at java.util.SubList.iterator(AbstractList.java:781)
at java.util.AbstractCollection.contains(AbstractCollection.java:94)
at java.util.Collections$SynchronizedCollection.contains(Collections.java:1567)
at java.util.Collections$SynchronizedCollection.contains(Collections.java:1567)
at java.util.AbstractCollection.removeAll(AbstractCollection.java:353)
at java.util.Collections$SynchronizedCollection.removeAll(Collections.java:1594)
at chapter11.Exercise22.main(Exercise22.java:42)
подскажите, пожалуста, как можно побороть его и почему оно у меня выскакивает???? Спасибо.... _________________ Итерация от человека, рекурсия от Бога... |
|
|
|
 |
Староверъ : 7629 Ктапубеп Откуда: Elfland
|
Июн 30, 2008 23:25 |
|
|
Один из случаев, когда выбрасывается это исключение, это при итерации коллекции и одновременном изменении ее элементов. Я так понимаю, что Collections.synchronizedList() создает новые потоки для работы с коллекцией. Вот и получается, что итерация происходит в одном потоке, а удаляются элементы в другом. Если убрать эту синхронизацию, то все "пучком".
Правда это только предположение. _________________ JTalks Open Source Project, JT Webinars, JT Interview |
|
|
|
 |
nazica : 1519 Администратор Откуда: Donetsk, UA
|
Июл 01, 2008 0:02 |
|
|
не, убрать синхронизацию не поможет делу. Перепишите строку кода
| Код: |
| List<Exercise22> list = Collections.synchronizedList(linkedlist.subList(8, 16)); |
так:
| Код: |
| List<Exercise22> list = Collections.synchronizedList(new LinkedList(linkedlist.subList(8, 16))); |
если вызывать просто subList(), то метод всего лишь оборачивает базовую коллекцию так:
| Код: |
public List<E> subList(int fromIndex, int toIndex) {
return new SubList<E>(this, fromIndex, toIndex);
} |
| Код: |
class SubList<E> extends AbstractList<E> {
private AbstractList<E> l;
private int offset;
private int size;
private int expectedModCount;
SubList(AbstractList<E> list, int fromIndex, int toIndex) {
// not important
l = list;
offset = fromIndex;
size = toIndex - fromIndex;
expectedModCount = l.modCount;
}
...
|
Думаю, что неприятности как раз связаны с тем, что используется обертка. _________________ Software and cathedrals are much the same - first we build them, then we pray
Последний раз редактировалось: nazica (Июл 01, 2008 0:08), всего редактировалось 1 раз |
|
|
|
 |
loz_a : 163 Новичок Откуда: Моршин
|
Июл 01, 2008 0:04 |
|
|
Да это я уже добавил когда облазил все интернеты и начитался всякого умного...
| Код: |
public static void main(String[] args) {
List<Exercise22> linkedlist = new LinkedList<Exercise22>());
for (int i = 0; i < 20; i++) {
linkedlist.add(new Exercise22(i));
}
printArray(linkedlist);
List<Exercise22> list = linkedlist.subList(8, 16);
System.out.println();
printArray(list);
synchronized (linkedlist) {
linkedlist.removeAll(list);
}
printArray(linkedlist);
}
} |
Результат тот же самий... Выбивае это мистическое исключение...  _________________ Итерация от человека, рекурсия от Бога... |
|
|
|
 |
loz_a : 163 Новичок Откуда: Моршин
|
Июл 01, 2008 0:11 |
|
|
спасибо... Пилюля подействовала...  _________________ Итерация от человека, рекурсия от Бога... |
|
|
|
 |
Староверъ : 7629 Ктапубеп Откуда: Elfland
|
Июл 01, 2008 6:46 |
|
|
|
|
|
|
 |
loz_a : 163 Новичок Откуда: Моршин
|
Июл 01, 2008 7:52 |
|
|
может IDE здесь имеет какое-то значение.. у меня Eclipse... _________________ Итерация от человека, рекурсия от Бога... |
|
|
|
 |
nazica : 1519 Администратор Откуда: Donetsk, UA
|
Июл 01, 2008 9:58 |
|
|
хм, а у меня не подествовало. Видно, пора на запчасти %) _________________ Software and cathedrals are much the same - first we build them, then we pray |
|
|
|
 |
Староверъ : 7629 Ктапубеп Откуда: Elfland
|
Июл 01, 2008 11:04 |
|
|
|
|
|
|
 |
Майоров Павел : 1460 Java Developer
|
Июл 06, 2008 10:22 |
|
|
А вот так не пробовали?
linkedlist.subList(8,16).clear(); //удаляет элементы с восьмого по пятнадцатый |
|
|
|
 |
Shreder : 101 Новичок Откуда: Kharkov, Ukraine
|
Июл 07, 2008 13:10 |
|
|
| loz_a писал(а): |
Есть до ужаса простая програмка....
| Код: |
import java.util.*;
List<Exercise22> linkedlist = Collections
.synchronizedList(new LinkedList<Exercise22>());
|
|
Попробуйте использовать
List<Exercise22> linkedlist = new Vector<Exercise22>();
У меня была подобная проблема и при переходе на вектор, проблема профиксилась сама собой. |
|
|
|
 |
Майоров Павел : 1460 Java Developer
|
Июл 07, 2008 13:50 |
|
|
Shreder, ну и какого черта вы советуете перейти на вектор, если это вам не помогло?!
PS для генерации подобного исключения достаточно таких строк кода:
| Код: |
List<Object> list = new LinkedList<Object>();
//теперь заполним список
...
//теперь совершим нечто страшное!
Iterator<Object> iter = list.getIterator();
list.add(null);
iter.next(); //ошибка!
|
То есть ошибка возникает при изменении списка в процессе его перебора. |
|
|
|
 |
Ybr : 7 Новичок
|
Авг 14, 2011 17:53 |
|
|
Доброго времени суток, господа.
Пишу простенькую программу. В одном из методов столкнулся с точно таким же исключением. Что пробовал:
| Староверъ писал(а): |
| Один из случаев, когда выбрасывается это исключение, это при итерации коллекции и одновременном изменении ее элементов. |
Проанализировал код. Итерация коллекции используется, но, вроде, никаких изменений этой коллекции я не делаю.
| nazica писал(а): |
| Думаю, что неприятности как раз связаны с тем, что используется обертка. |
Попробовал вместо Character использовать char - тоже никак не повлияло.
Код метода (вылетает на строке № 27):
| Код: |
public String BreveCorrector (int i, String s) {
String desBreve;// строка, в которой произошла замена найденной комбинации на бреве
ArrayList<Character> ordinary = new ArrayList<Character>();// массив для букв без бреве
ArrayList<Character> abbreve = new ArrayList<Character>();// массив для букв с бреве
Iterator<Character> o = ordinary.iterator();
int j = -1;
char c;
// заполнение таблицы соответствия
ordinary.add('a'); ordinary.add('A');
ordinary.add('e'); ordinary.add('E');
ordinary.add('i'); ordinary.add('I');
ordinary.add('o'); ordinary.add('O');
ordinary.add('u'); ordinary.add('U');
abbreve.add('ă'); abbreve.add('Ă');
abbreve.add('ĕ'); abbreve.add('Ĕ');
abbreve.add('ĭ'); abbreve.add('Ĭ');
abbreve.add('ŏ'); abbreve.add('Ŏ');
abbreve.add('ŭ'); abbreve.add('Ŭ');
// процесс замены найденной комбинации на гласную с бреве
desBreve = s.substring(0, i);// копируется строка s от начала до того места, где
// надо произвести замену
while (o.hasNext()) {// замена обычной буквы на букву с бреве
c = o.next(); j++;
if (!(c != s.charAt(i+1))) desBreve = desBreve + abbreve.get(j).toString();
}
desBreve = desBreve + s.substring(i, s.length()-1);// копирование оставшейся части строки s
return desBreve;
} |
Выдаваемая ошибка:
| Цитата: |
| Exception in thread "main" java.util.ConcurrentModificationException <и указание, на каких строках искать> |
Интересно будет выслушать ваши мнения. |
|
|
|
 |
Майоров Павел : 1460 Java Developer
|
Авг 14, 2011 18:17 |
|
|
Ваша проблема в том, что вот эта строчка
| Код: |
| Iterator<Character> o = ordinary.iterator(); |
стоит перед
| Код: |
ordinary.add('a'); ordinary.add('A');
ordinary.add('e'); ordinary.add('E');
ordinary.add('i'); ordinary.add('I');
ordinary.add('o'); ordinary.add('O');
ordinary.add('u'); ordinary.add('U'); |
и в итоге получается, что в процессе итерации (который начался в строке 6) меняется содержимое.
Поставьте создание итератора сразу перед циклом while и исключение исчезнет
PS возможно, вместо ArrayList<Character> в этом куске кода следовало бы использовать строки:
| Код: |
String ordinary = "aAeEiIoOuU";
String abbreve = "ăĂĕĔĭĬŏŎŭŬ"; |
Строчек кода будет меньше, да и смотреть, какая буква какой соответствует, много проще.
PPS давно уже за форумом не слежу, а уведомления все приходят и приходят  |
|
|
|
 |
Ybr : 7 Новичок
|
Авг 14, 2011 20:20 |
|
|
| Майоров Павел писал(а): |
| Поставьте создание итератора сразу перед циклом while и исключение исчезнет |
Спасибо, это сработало. Буду знать, что итерирование начинается в месте определения переменной итерации.
| Майоров Павел писал(а): |
| PS возможно, вместо ArrayList<Character> в этом куске кода следовало бы использовать строки<...> |
Это моя вечная проблема. Если ухо можно чесать рукой, то я непременно попробую это сделать и левой ногой =)
Поправил.
| Майоров Павел писал(а): |
PPS давно уже за форумом не слежу, а уведомления все приходят и приходят  |
Это на руку новичкам вроде меня Спасибо за помощь! |
|
|
|
 |
|
|
|