вопрос по списку java удалить - PullRequest
2 голосов
/ 04 апреля 2011

Метод public boolean remove(Object o) из List удаляет объект из списка, но не перемещает следующие элементы. Просто обнуляет значение объекта.
ИМХО, это не интуитивный выбор дизайна, поскольку размер списка до и после удаления остается неизменным.
Есть ли элегантный способ получить список со смещенными элементами?

Спасибо

Ответы [ 6 ]

4 голосов
/ 04 апреля 2011

Нет, это не то, что он делает. Элемент удаляется, а все последующие индексы уменьшаются на единицу. Что заставляет вас думать, что он действует по-другому?

3 голосов
/ 04 апреля 2011

Согласно Java API здесь это говорит о том, что функция удаления List DOES смещается

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

EDIT:

Основной класс:

import java.util.ArrayList;
import java.util.Iterator;


public class Main {


    public static void main(String[] args) {


        ArrayList<A> x = new ArrayList<A>();
        A one = new A("one");
        A two = new A("two");
        A three = new A("three");
        A four = new A("four");
        A five = new A("five");
        A six = new A("six");
        A seven = new A("seven");
        A eight = new A("eight");
        A nine = new A("nine");
        A ten = new A("ten");

        x.add(one);
        x.add(two);
        x.add(three);
        x.add(four);
        x.add(five);
        x.add(six);
        x.add(seven);
        x.add(eight);
        x.add(nine);
        x.add(ten);

        for(A item:x){
            System.out.println(item.getStr());
        }

        x.remove(four);

        Iterator<A> i = x.iterator();
        while(i.hasNext()){
            A item = i.next();
            System.out.println(item.getStr());
        }
    }
}

Класс A:

public class A {
    private String str;

    public A(String x){
        this.str = x;
    }

    public String getStr(){
        return this.str;
    }

}

работает отлично! нет исключения нулевого указателя. Вот как это должно быть сделано. первый цикл For - это альтернативный синтаксис того, что я сделал с объектом Iterator. На самом деле Java автоматически переводит первый цикл for в нечто похожее на цикл while.

2 голосов
/ 06 мая 2014

Если вы посмотрите на реализацию удаления ArrayList , он использует локальный метод fastRemove (index) следующим образом: -

/ * * Закрытый метод удаления, который пропускает проверку границ и не *вернуть значение удалено.* /

private void fastRemove(int index) {
    modCount++;
    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    elementData[--size] = null; // Let gc do its work
}

Он использует arraycopy, который является доказательством того, что вы получаете новый список свежих объектов, а не заполненный ноль между ними.Это доказательство?

1 голос
/ 02 марта 2016

Либо ваше наблюдение неверно, либо вы используете какую-то другую реализацию List (а не ArrayList), которая не сдвигает элементы справа от удаляемого элемента. Вы можете разместить свой код?

Если вы посмотрите на исходный код java.util.ArrayList в JDK8, вы увидите, что метод remove (Object o) эффективно копирует элементы справа от удаляемого элемента в тот же массив, начиная с индекса удаляемого элемента. Посмотрите исходный код ArrayList для получения дополнительной информации:

1 голос
/ 04 апреля 2011

Контракт на java.util.List подразумевает, что вызов remove приведет к уменьшению size(). Если вы говорите конкретно о java.util.ArrayList, то вы можете быть правы в том, что внутренний массив не смещает свои элементы, но это деталь реализации, которая не должна иметь значения для вас в 99% всех случаев. Если это все еще имеет значение, то вы пытаетесь оптимизировать для конкретной ситуации, и вам, вероятно, следует реализовать свой собственный List или использовать что-то вроде java.util.LinkedList.

0 голосов
/ 05 апреля 2011

Если вам нужен только массив данных, просто позвоните toArray().

...