Как удалить все из ArrayList в Java, но первый элемент

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

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

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

Ответы

Ответ 1

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

Вы можете попробовать следующее:

Object obj = mapOverlays.get(0); // remember first item
mapOverlays.clear(); // clear complete list
mapOverlays.add(obj); // add first item

Ответ 2

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

mapOverlays.subList(1, mapOverlays.size()).clear();

Ответ 3

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

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

Ответ 4

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

E temp = mapOverlays.get(0);
mapOverlays = new ArrayList<E>().add(temp);

Ответ 5

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

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

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

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

Ответ 6

Simple.

mapOverlays = Collections.singletonList(mapOverlays.get(0));

Ответ 7

Я предполагаю, что 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!

Ответ 8

Если вы используете реализацию java.util.List вместо массива, размер массива уменьшается каждый раз, когда вы удаляете что-то, а элемент n+1 заменяет элемент n. Этот код в конечном итоге приведет к ArrayIndecOutOfBoundsException, когда n станет greated, чем последний индекс в списке.

Java также имеет тип массива, и размер этого нельзя изменить:

Object[] mapOverlay = //initialize the array here
int size = mapOverlay.length;
for(int n=1;n<size;n++)
{
    mapOverlay[n] = null;
}

Я не знаю PHP, но это похоже на то, что вы после. Однако реализации List более гибкие и удобные в использовании, чем массивы.

EDIT: здесь ссылка на Javadoc List.remove(int): http://java.sun.com/javase/6/docs/api/java/util/List.html#remove%28int%29

Ответ 9

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

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

Ответ 10

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

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

EDIT (см. комментарий от Адама Крама)

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

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

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

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



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