2016-01-05 3 views
2

Во время работы на некоторых Java проекта я столкнулся с этой своеобразной ошибки:Java - Index Out Of Bounds Exception: индекс: 1, размер: 2

java.lang.IndexOutOfBoundsException: Index: 1, Size: 2 

Как может быть индекс из исключения ограничивает? Индекс 1 означает, что он пытается получить второй элемент, размер 2 означает, что есть два элемента, поэтому не должно быть проблем, нет?

Контекст:

У меня есть следующие функции:

public int howManyAgents(){ 
    // cell is a class that can have 0 or multiple objects 
    // I get a list of cells that contain at least 1 agent 
    List<Cell> cellsWithAgents = getNonEmptyCells(); 

    // initializing a counter 
    int agentsCount = 0; 

    for(int i=0; i<cellsWithAgents.size(); i++){ 

     // For every cell in the list I add to the counter the number of  
     // agents that cell contains 
     agentsCount += cellsWithAgents.get(i).howManyAgents(); 
    } 
    return agentsCount; 
} 

Теперь проблема заключалась в том, что я получил исключения нулевого указателя на строку:

agentsCount += cellsWithAgents.get(i).howManyAgents(); 

Я хочу отладить код, но эта функция вызывается много раз во время работы программы, а исключения с нулевым указателем появляются в разные моменты времени (через 10 секунд после 1 минуты через 5 минут). Так что я пытался придумать метод, чтобы иметь электронную контрольную точку, когда клетка равна нулю, так что я придумал этот код:

public int howManyAgents(){ 
    // cell is a class that can have 0 or multiple objects 
    // I get a list of cells that contain at least 1 agent 
    List<Cell> cellsWithAgents = getNonEmptyCells(); 

    // initializing a counter 
    int agentsCount = 0; 

    for(int i=0; i<cellsWithAgents.size(); i++){ 

     int pass; 
     if (null == cellsWithAgents.get(i)) 
      pass = 1; // breakpoint here 

     // For every cell in the list I add to the counter the number of  
     // agents that cell contains 
     agentsCount += cellsWithAgents.get(i).howManyAgents(); 
    } 
    return agentsCount; 
} 

Конечно, это не самый лучший способ. Самый логичный путь - это окружение кода с помощью try/catch и установка точки останова. Дело в том, что код выше не работает. Он не останавливается на точке останова, но вместо этого он бросил индекс выходит за границы исключений на линии:

if (null == cellsWithAgents.get(i)) 

Почему? Как можно исключить индекс из связанного исключения, если, по-видимому, индекс находится в границах?

Edit: изменена ошибка в копировании кода

Update: Я пытался понять, почему исключения нулевого указателя появляется с TRY/поймать и поставить точку останова. Кажется, что cellWithAgents иногда содержат нуль. Это, скорее всего, из-за параллелизма, как заявил @rlinden.

О параллелизме: есть некоторые ячейки, которые могут содержать агентов. Существует переменное количество агентов, которые могут перемещаться между ячейками. Существует специальный агент, который пытается подсчитать количество движущихся агентов (используя эту функцию). Таким образом, только один агент (поток) может использовать эту функцию, но несколько агентов могут изменять ячейки (и, таким образом, беспорядок с результатами getNonEmptyCells() и howManyAgents()).

Тем не менее, как можно получить индекс за пределы с размером 2 и индексом 1? Это невозможно из-за параллелизма, не так ли? Потому что только этот поток может изменить список cellWithAgents. Таким образом, даже если один из элементов в списке становится нулевым, список все еще содержит это количество указателей, поэтому размер списка не может измениться. Или это может быть так, что я скучаю? И как можно объяснить, что трассировка трассировки стека Индекс: 1 Размер: 2?

+0

Установка точки останова на линии, на которую вы положили ее, бесполезна. Ошибка возникает при попытке доступа к индексу 'i'th, которого не существует. Что касается _why_, это за гранью, я буду продолжать смотреть. – Arc676

+0

Почему ваше нулевое сравнение между ячейкамиWithType? – rlinden

+0

AS для того, как это исключение происходит, вне меня, однако то, что бросается в глаза, это: вы перебираете ячейки с помощью агентов, но используете этот индекс для доступа к CellsWithTypes. – bwright

ответ

1

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

Это связано с тем, что строка cellsWithAgents = getNonEmptyCells(); не создает копию, а ссылку на возвращаемое значение getNonEmptyCells(). Таким образом, если этот метод повторно использует возвращаемый объект, возможно, что первое выполнение показало бы, что было два, но сопутствующая нить изменила размер содержимого на менее чем 2.

+0

Да, похоже, что это из-за параллелизма. Спасибо. Я просто поместил синхронизацию вокруг блока кода и не стал больше ошибок. Очень странно, как Java может выбросить такую ​​странную ошибку, только из-за одновременных изменений. –

+0

Странность объяснима. Для производительности метод size() вызывается только в начале цикла. После этого петля предполагает, что она остается неизменной (на 2). Когда вы меняете список в одновременном процессе, цикл не информируется и поэтому пытается найти элемент списка, которого больше нет. – rlinden

+0

О, хорошо. В этом есть смысл. Большое спасибо! –

2

Новая Идея

Попробуйте изменить цикл и посмотреть, если ошибка повторяется:

int agentsCount = 0; 
for(Cell cell : getNonEmptyCells()) { 
    if(cell != null) { 
     agentsCount += cell.howManyAgents(); 
    } else { 
     System.out.println("Found a null cell"); 
    } 
} 
+0

О, черт возьми, мне очень жаль. Это была ошибка, я только что ее исправил. Это тот же список cellWithAgents –

+0

Так что опечатка была в вашем коде (исправлена ​​сейчас) или в вопросе (у вас все еще есть ошибка?) – Jan

+0

А вы уверены, что этот список выбрал ошибку? На этой линии? Не может быть howManyAgents()? – Jan

1

Проблема в том, что программа выбрасывает исключение в cellsWithType.get(i) , Что вы можете сделать, либо поставить точку останова на if (null == cellsWithType.get(i)) и попробовать отладить ее. Или измените его на,

if (i >= cellsWithType.size()) 
     pass = 1; // breakpoint here 
+0

Да, это была ошибка при копировании кода. Я исправил его, это тот же список cellWithAgents. Прошу прощения за ошибку. –

Смежные вопросы