Как удалить все из ArrayList в Java, кроме первого элемента - PullRequest
18 голосов
/ 23 июня 2010

Я новичок в программировании на Java, программирую на php, поэтому я привык к такому типу цикла:

int size = mapOverlays.size();
for(int n=1;n<size;n++)
{
    mapOverlays.remove(n);
}

Итак, я хочу удалить все, кроме первого элемента, так почему же это не работает? Как я понял, после удаления ключи массива переставляются или нет?

Ответы [ 11 ]

99 голосов
/ 23 июня 2010

Вы можете использовать

mapOverlays.subList(1, mapOverlays.size()).clear();
22 голосов
/ 23 июня 2010

Как я понял, после удаления ключи массива переставляются или нет? Да, элемент, который был в позиции 2, находится в позиции 1 после того, как вы удалили элемент в позиции 1.

Вы можете попробовать это:

Object obj = mapOverlays.get(0); // remember first item
mapOverlays.clear(); // clear complete list
mapOverlays.add(obj); // add first item
7 голосов
/ 23 июня 2010

Почему бы вам не попробовать назад?

int size = itemizedOverlay.size();
for(int n=size-1;n>0;n--)
{
    mapOverlays.remove(n);
}
4 голосов
/ 23 июня 2010

Я думаю, что было бы быстрее создать новый ArrayList только с первым элементом внутри.что-то вроде:

E temp = mapOverlays.get(0);
mapOverlays = new ArrayList<E>().add(temp);
2 голосов
/ 23 июня 2010

Простой.

mapOverlays = Collections.singletonList(mapOverlays.get(0));
2 голосов
/ 23 июня 2010

An ArrayList имеет целочисленные индексы от 0 до size() - 1.Вы можете сделать:

int size = mapOverlays.size();
for(int n=1;n<size;n++)
{
    mapOverlays.remove(1);
}

Это, вероятно, соответствует тому, что вы ожидаете от PHP.Он работает, постоянно удаляя 1-й элемент, который изменяется.Однако это имеет низкую производительность, поскольку внутренний массив должен постоянно смещаться вниз.Лучше использовать clear() или идти в обратном порядке.

Это очень плохо removeRange защищен, поскольку это было бы удобно для этого типа операции.

1 голос
/ 23 июня 2010

Я предполагаю, что mapOverlays содержит ссылку ArrayList.

Если mapOverlays объявлен как List или ArrayList, то mapOverlays.remove(n) будет ссылаться на remove(int) метод, который удаляет объект с заданным смещением.(Пока все хорошо ...)

Когда вы удаляете элемент nth массива, используя remove(int), элементы, начинающиеся с позиции n + 1 и, прежде всего, сдвигаются вниз на единицу.Так что то, что вы делаете, в большинстве случаев не сработает.(Фактически, вы, вероятно, удалите примерно половину элементов, которые хотите удалить, а затем получите IndexOutOfBoundsException.)

Лучшее решение: либо

    for (int i = size - 1; i > 0; i--) {
        mapOverlays.remove(i);
    }

, либо

    tmp = mapOverlays.remove(0);
    mapOverlays.clear();
    mapOverlays.add(tmp);

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

Однако, если mapOverlays объявлен как Collection, remove(n) свяжется с перегрузкой remove(<E>), которая удаляет объект, соответствующий его аргументу.В зависимости от объявленного типа, это либо выдаст ошибку компиляции, либо int будет автоматически упакован как Integer, и вы (вероятно) ничего не удалите. GOTCHA!

0 голосов
/ 27 июня 2010
0 голосов
/ 23 июня 2010

Используйте цикл while, чтобы удалить все после первого элемента:

while (mapOverlays.size() > 1) {
    mapOverlays.remove(1);
}

РЕДАКТИРОВАТЬ (см. Комментарий Адама Крума)

Если производительность является проблемой, вы должны использовать это

while (mapOverlays.size() > 1) {
    mapOverlays.remove(mapOverlays.size()-1);
}

даже небольшая микрооптимизация

int last = mapOverlays.size() - 1;
while (last >= 1) {
    mapOverlays.remove(last);
    last -= 1;
}



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

0 голосов
/ 23 июня 2010
int size = mapOverlays.size();
for(int n=0;n<size;n++)
{
    mapOverlays.remove(n);
}

В java, если mapOverlays является списком, он начинается с 0 в качестве первого индекса. Так что n = 0 в цикле for.

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