2014-02-21 4 views
0

У меня есть код для пиццы, который выполняет итерацию по списку объектов и проверяет, сталкиваются они или нет. Если кто-то сталкивается, он удаляется из ArrayList.Неожиданное поведение с ArrayList.remove()

for (int i = 0; i < arrayList.size(); i++) { 
    Object c = arrayList.get(i); 
    if (Rect.intersects(foo.getRect(), c.getRect())) { //Android function, checks if the two rectangles are inside each other. 
     foo.setPosY(c.getPosY() + 11); // Always works. 
     foo.setVelY(bird.getVelY() * -1); // Always works. 
     arrayList.remove(i); // Occasionally fails under special circumcisions. 
    } 
} 

При открытии приложения в первый раз это прекрасно работает. Однако, если я выйду с помощью кнопки «Назад», а затем быстро откройте приложение, все будет работать , за исключением, изредка удаляется объект из ArrayList.

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

+2

Как это может код работать? 'c' объявлен как' Object', а 'Object' не имеет' .get *() 'методов ... Или это что-то еще, чем' java.lang.Object'? – fge

+3

Во-первых, вы всегда пропускаете элемент после его удаления. Либо работайте с обратной стороны, либо уменьшайте 'i' после операции' remove', или используйте итератор. –

+0

@fge, Извините. Я имел в виду, чтобы это подразумевало мой собственный класс. Это просто объект foo, который имеет право, которое вы можете получить. – Jimicrackcorn

ответ

5

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

Так что, если вы звоните remove(2), следующий элемент, который вы хотите посмотреть в настоящее время имеет индекс 2.

Общие способы фиксации этого:

  • работать в обратном направлении:

    for (int i = arrayList.size() - 1; i >= 0; i--) 
    
  • Используйте итератор вместо:

    for (Iterator<Foo> iterator = arrayList.iterator(); iterator.hasNext();) { 
        Foo c = iterator.next(); 
        if (...) { 
         iterator.remove(); 
        } 
    } 
    
+0

Ничего себе, спасибо. Я не могу поверить, как долго я это пропустил. Я исправил эту проблему и протестировал ее. К сожалению, проблема все еще сохраняется. Я благодарен вам за то, что вы указали на это. Я буду более внимателен в будущем. – Jimicrackcorn

+0

@ user3321627: Если проблема по-прежнему сохраняется, вы должны отредактировать свой вопрос, чтобы предоставить больше диагностической информации. 'ArrayList.remove()' defin * * do * work, поэтому я предлагаю вам записать содержимое до и после вызова 'remove() ... –

+0

@Skeet, да, он работает на 100%, пока он не находится в последний список. Я не могу заставить его показать это поведение в новом начале. Я пробовал еще 100 раз. Он будет делать это только после того, как он будет запущен, и он будет делать это часто, но не каждый раз. Я пробовал использовать режим отладки, и он будет показывать то же поведение, но только при фактическом запуске. Он не сделает этого, пока я перехожу. – Jimicrackcorn

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