Цикл и массив и удаление элементов по указанному индексу - PullRequest
4 голосов
/ 16 февраля 2012

Я пытался выполнить упражнение, в котором я добавил бы 1000 элементов в массив и затем снова систематически удалил их из списка (указав индекс). Идея заключается в том, чтобы сравнить производительность LinkedList с ArrayList.

int totalObjects = 0;
    for(int i = 0; i < 1000; i++)
    {
        totalObjects += 1;
        al.add("Object " + totalObjects);

    }
     System.out.println("The Arraylist size is " + al.size());

Если я сделаю следующее, будет удалена только половина элементов ... почему?

for(int index = 0; index < al.size(); index++)
    {

        al.remove(index);

    }
    System.out.println("The Arraylist size after removal is " + al.size());

С уважением Arian

Ответы [ 6 ]

12 голосов
/ 16 февраля 2012

Это происходит потому, что вы изменяете индексы, удаляя. Если вы удаляете элемент 0, элемент 1 теперь становится элементом 0. Теперь, когда вы в следующий раз удалите 1, это то, что раньше было элементом 2, и что было элементом 1, все еще существует с индексом 0.

Самый простой способ избежать этого - вернуться назад от конца к началу.

альтернативно, вы можете просто удалить индекс 0, пока ArrayList не станет пустым.

8 голосов
/ 16 февраля 2012

Помните, что вы можете удалить все элементы одновременно, просто используя метод clear(). В вашем коде проблема заключается в том, что список изменяется в то же время, когда вы выполняете его итерацию, эффективно уменьшая его размер, поэтому условие index < al.size() не выполняется. Попробуйте вместо этого:

for (int index = 0, n = al.size(); index < n; index++)
    al.remove(0);

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

for (int idx = al.size() - 1; idx >= 0; idx--)
    al.remove(idx);
2 голосов
/ 16 февраля 2012

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

Исправление было бы сделать это.

int size = al.size();
for(int index = 0; index < size; index++ ) {

тогда работай. Таким образом, размер не меняется.

Еще одна вещь, которую следует помнить, это то, что когда вы удаляете что-то из массива с индексом 0, индекс 1 становится индексом 0. Поэтому, возможно, было бы лучше выполнить итерацию с

int index = al.size(); index >=0 ; index--
2 голосов
/ 16 февраля 2012

Поскольку при удалении элементов из ArrayList его индекс обновляется.Таким образом, вы удаляете элемент в позиции 0, а элемент в позиции 1 теперь находится в позиции индекса 0.Поэтому при удалении элемента с индексом 1 вы удаляете элемент с индексом 2 оригинала ArrayList и т. Д.

1 голос
/ 16 февраля 2012

это нормально, что только половина списка пуста, потому что когда вы удаляете элементы из списка, размер списка уменьшается, но индекс увеличивается. И они встречаются в середине. Если вы действительно хотите удалить элементы один за другим, и удалить от последнего до первого элемента. Я предлагаю вам использовать:

while (!al.isEmpty())
{

    al.remove(al.indexOf(al.size()-1));

}
1 голос
/ 16 февраля 2012

При удалении предмета из списка он сокращается.

Допустим, у вас есть предметы 0 1 и 2

Ваш индекс 0

Вы удаляете 0, ваш индекс теперь равен 1, вы удаляете 2, потому что теперь он равен индексу 1.

Имеет смысл?

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