ArrayList обращаясь к элементу, который должен был быть удален - PullRequest
0 голосов
/ 11 февраля 2011

Я использую Java для проекта интеллектуального анализа данных, и у меня возникла странная проблема с ArrayList.

ArrayList (vendAttribs) содержит имена всех атрибутов, еще не использованных в текущей ветви дерева решений. В начале цикла выбирается атрибут, и индекс этого атрибута в ArrayList сохраняется в selectedAttribute. Логика выполняется, затем элемент удаляется из списка и выбирается другой.

Программа работала не так, как ожидалось, поэтому я использовал для каждого цикла отображение текущего содержимого ArrayList перед каждым выбором атрибута, чтобы я мог проверить его содержимое.

Вот что я получил:

availAttribs contains ...
-Color
-size
-act
-age
Chose attribute #1: size

availAttribs contains ...
-Color
-act
-age
Chose attribute #1: size

Атрибуты выбираются случайным образом:

for(String s : availAttribs) {
   System.out.println("   -" + s); 
}   
chosenAttribute = random.nextInt(availAttribs.size() - 1); 
System.out.println("   Chose attribute #" + chosenAttribute + ": " +
      trainSet.attribute(chosenAttribute).name());

// other stuff here

availAttribs.remove(chosenAttribute);

Все это в цикле while, проверяющем условие выхода. Я бы подумал, что если элемент не был успешно удален, он будет отображаться, когда я перебираю список и распечатываю каждый элемент, но, очевидно, он все еще может получить к ним доступ.

Edit: Случайное было объявлено вне цикла while:

Random random = new Random(System.currentTimeMillis() );

Ответы [ 3 ]

1 голос
/ 11 февраля 2011

ArrayList.remove (Obj) удаляет первый (самый низкий индекс) объект, который подчиняется obj.equals (Obj). Вы звоните удалить по индексу:

availAttribs.remove(chosenAttribute);

должно быть

availAttribs.remove(availAttribs.get(chosenAttribute));

т.е. значение элемента по индексу i, а не i;

0 голосов
/ 11 февраля 2011

Я выяснил ответ, пытаясь объяснить часть кода в ответ на комментарий. selectedAtrribute - это индекс по отношению к ArrayList, и из-за того, как я заполняю ArrayList, он соответствует индексам, которые структура данных, которую я использую, внутренне присваивает каждому атрибуту. Когда я удаляю элемент из ArrayList, все после него скользят вперед, и они больше не синхронизируются.

Поскольку мой оператор отладки извлекает имя из структуры данных, а не из самого ArrayList, он отображает неправильное имя, пока массив ведет себя так, как ожидалось.

Не уверен, почему я не заметил этого раньше.

0 голосов
/ 11 февраля 2011

Полагаю, вы вызываете List.remove(...) для целочисленного объекта, а не для примитива int. Какой тип переменной chosenAttribute?

Вызов метода remove (...) с объектом вызывает метод remove (object), например:

Integer chosenAttribute = ...
availAttribs.remove(chosenAttribute);

будет зацикливаться вечно, однако:

int chosenAttribute = ...
availAttribs.remove(chosenAttribute);

завершается как положено.

Вы можете получить примитив int для индекса и вызвать List.remove(int), или вы можете получить объект по индексу и вызвать List.remove(object). Либо должно работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...