2016-04-06 5 views
0

У меня есть следующий снайперский код, где я хочу удалить все '0' из массива p4. Этот массив будет помещен в arraylist amountOfColorPoints. Для цикла Loop должен работать до конца размера списка, но он больше не выполняется после того, как первый «0» был удален, как я могу видеть на консоли. В чем проблема? Может ли кто-нибудь помочь мне?Почему цикл for не продолжается

int[] p4={0,0,4}; 

ArrayList<Integer> amountOfColorPoints = new ArrayList<>(); 

. . .

for(int p=0; p<amountOfColorPoints.size(); p++) { 
       if (amountOfColorPoints.get(p) == 0) 
        amountOfColorPoints.remove(p);} 
+4

Вам нужен «Итератор» –

+0

Подумайте о том, что вы делаете, сначала удалите первый 0, оставляя свою коллекцию как '{0,4}', тогда вы проверяете, является ли второе значение 0, это не так 4, и ваша петля завершается. –

+1

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

ответ

3

Безопасный способ удаления элементов из коллекции (в то время как итерация его) находится с Iterator.remove() как Javadoc отмечает

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

Нечто подобное,

Iterator<Integer> iter = amountOfColorPoints.iterator(); 
while (iter.hasNext()) { 
    if (iter.next() == 0) { 
     iter.remove(); 
    } 
} 
0

На каждой итерации цикла размер массива пересчитывается. Таким образом, при удалении элемента на позиции 0, размер массива становится равным 2, второй 0 смещается в положение 0, а р уже 1, так что вы пропустите второй 0.

Правильный код:

Iterator<Integer> iter = amountOfColorPoints.iterator(); 
    while (iter.hasNext()) { 
    if (iter.next() == 0) { 
     iter.remove(); 
    } 
    } 
0

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

Для того, чтобы вам код работать, уменьшает индекс:

for(int p=0; p<amountOfColorPoints.size(); p++) { 
    if (amountOfColorPoints.get(p) == 0) 
     amountOfColorPoints.remove(p--); // decrement 
} 

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

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