IndexOutOfBoundsException - только иногда? - PullRequest
0 голосов
/ 11 июля 2011

Я постоянно получаю случайные ошибки java.lang.IndexOutOfBoundsException в моей программе.Что я делаю неправильно?Программа работает нормально, это действительно длинный цикл for, но для некоторых элементов мне кажется, что я получаю эту ошибку, а затем переходит к следующему элементу и работает нормально.это ошибки?

Ответы [ 4 ]

3 голосов
/ 11 июля 2011

Для тех, кто думает, что это массив, это скорее список.

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

Вы изменяете свой Список во время работы этого цикла. Время от времени вы удаляете элемент. Время от времени вы смотрите на последний элемент size()-1. Когда порядок операций выглядит так:

 (some thread)
 remove an element from response.getSegments().getSegmentInfo()
 (some possibly other thread)
 lookup up the size()-1 element of the above

Вы получаете доступ к элементу, который больше не существует, и вызовет исключение IndexOutOfBoundsException.

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

Простой способ сделать последнее - сделать копию списка (но не элементов списка) и выполнить итерацию по копии.

--- Отредактировано, поскольку проблема резко изменилась в редактировании после написания вышеупомянутого ---

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

Кроме того, вы, вероятно, не хотите пропускать элементы, скорее всего, вы действительно хотите получить доступ ко всем классам кабины в сегментеInfo, а не только к 3-му классу Cabin в 3-м сегменте информации и т. Д.

1 голос
/ 11 июля 2011

Вы используете i как индекс для списка информации о сегментах и для списка классов кабины . Это пахнет как источник вашей проблемы.

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


Изменен код для отображения проблемы (угадал типы, замените правильными именами классов)

List<SegmentInfo> segmentInfos = response.getSegments().getSegmentInfo();

for (int i = 0; i < segmentInfos.size()-1; i++) {
   // use i to get actual segmentInfo
   SegmentInfo segmentInfo = segmentInfos.get(i);
   List<CabinClass> cabinClasses = segmentInfo.getCabinSummary.getCabinClass();

   // use i again to get actual cabin class ???
   CabinClass cabinClass = cabinClasses.get(i);

   reservedSeats = cabinClass.getAmountOfResSeat();
   usedSeats = cabinClass.getAmountOfUsedSeat();

   System.out.println("Reserved Seats: " + reservedSeats);
   System.out.println("Used Seats    : " + usedSeats);
}
1 голос
/ 11 июля 2011

Вы, похоже, используете i для индексации двух совершенно отдельных List объектов:

response.getSegments().getSegmentInfo().get(i) // indexing into response.getSegments().getSegmentInfo()
.getCabinSummary().getCabinClass().get(i) // indexing into getCabinSummary().getCabinClass()
.getAmountOfResSeat();

Это выглядит неправильно для меня.Это должно произойти таким образом?И является ли список, возвращаемый getCabinClass() гарантированно равным , по крайней мере, , если список, возвращаемый getSegmentInfo()?

0 голосов
/ 11 июля 2011

Предполагая, что response.getSegments().getSegmentInfo() всегда возвращает массив одинакового размера, вызов .get(i) для него должен быть безопасным, учитывая заголовок цикла (но знаете ли вы, что пропускаете последний элемент?) Однако вы уверены, чточто .getCabinSummary() вернет массив размером с массив getSegmentInfo()?Выглядит подозрительно, что вы используете i для выполнения поиска в двух разных массивах.

Вы можете разбить первую строку в теле цикла на две отдельные строки (я только предполагаю имена типов здесь):

List<SegmentInfo> segmentInfo = response.getSegments().getSegmentInfo().get(i);
reservedSeats = segmentInfo.getCabinSummary().get(i).getAmountOfResSeat();

Тогда вы увидите, какой поиск вызывает сбой.

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