2016-03-07 3 views
1

Предположим следующую ситуацию в цикле:размер списка имеет неожиданное значение

LinkedList<String> myList = someMethodReturnsList(); 
int start = 0, end = 0; 

while (end < myList.size() && someOtherCondition) 
    ++end; 

List<String> subList = myList.sublist(start, end); 

... (do stuff and possibly alter list) 

start = end; 

Я с ситуацией, когда только иногда, что вызов sublist сгенерирует IndexOutOfBoundsException. Учитывая мой первый тест end < myList.size(), это смутило меня, поэтому я написал несколько отладочных кодов. Мой отлаживать код сказал мне, что где-то между while петлей и вызывающей sublist, моя end значения заканчивало тем, что 34 в то время как myList.size() возвращался 33.

Как это вообще возможно? В моей программе нет других потоков, которые могут работать в этом списке, так как мой цикл проверки прошел и увеличил end до 34?

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

+0

Единственное логическое объяснение заключается в том, что либо someOtherCondition изменяет List, либо someMethodReturnsList сохраняет ссылку на Список и модифицирует его. – VGR

+0

Оба звука звучат логично. Однако 'someMethodReturnsList' всегда создает экземпляр' new', а 'someOtherCondition' просто проверяет свойство (только чтение) из' end'th элемента 'myList'. – 2mac

+0

Интересно. Можно ли включить эти два? И, кстати, 'LinkedList' определенно не является хорошим классом для выполнения' myList.get (end) 'и' myList.subList'. – Marwin

ответ

0

Ага! Я понял это на основе тщательной отладки.

Оказывается, на итерации цикла, где происходит это исключение, значение end является начиная на 34. Таким образом, цикл проходит приращение, и возникает ошибка индекса.

Причина в том, что в предыдущей итерации myList.size() было 36, но в течение этого цикла было удалено 3 элемента.

-1

Выглядит как классическая ошибка «по очереди». Вероятно, у вас есть end, равный myList.size(), а затем ссылаясь на еще один вперед, чем вы хотите. Из вашего цикла while, например. если массив был 5 элементов:

while (end < 5 && conditions) 
{ 
    ++end; //results in end being 5 
} 

затем позже он идет

List<String> subList = myList.sublist(0, 5); 

и 5 находится за пределами, как массив имеет только индексы 0,1,2,3,4

Я думаю, вы должны либо сделать его while (end+1 < 5 && conditions) или myList.sublist(0, end-1);

EDIT: Принадлежит к @Justen, за указание на мою ошибку.

0

То, что вы описываете, невозможно.

На самом деле, единственный способ для этого - ваша собственная отладка: есть функции IDE, такие как проверка элементов кода, выполняющих части кода, в то время как приложение приостанавливается на контрольной точке.

Вы должны изменить значение end с помощью инструментов отладчика.

+0

Я не использую свой отладчик в этом случае. Я знаю, что описанная мной ситуация не может быть возможной. Единственный способ иметь смысл в том, что 'myList.size()' равно 34 во время цикла и как-то уменьшается после него. Вот почему я пришел сюда; Я не понимаю, как это может произойти вообще. – 2mac

0

Моя догадка вдоль линий, что сказал @Jalitha, от одного: вызов Подсписок должен быть:

List<String> subList=myList.sublist(start,end-1); 

Причина, по которой вы иногда получаете правильное число, вероятно, связано с someOtherCondition ,

Помните, что размер() на 1 больше, чем последний индекс и сублист работает с индексами.

я поставил бы это в комментариях, но не смог из-за репутацию :(

+0

спасибо за пикап! Не понял, я чувствую себя немного глупо сейчас: P Я тоже отредактирую свой ответ. –

+0

Lol np, но похоже, что он либо не работал на 2mac, либо недостаточно ясно? – Justen

+0

Не обращайте внимания, я только что видел другие комментарии и сам пробовал, используя размер, должен работать нормально. Я думаю, нам, возможно, придется увидеть больше фактического кода, чтобы понять это? – Justen

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