Nano Hash - криптовалюты, майнинг, программирование

вопрос в списке java удалить

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

Спасибо


  • но не сдвигает следующие элементы. Просто обнуляет значение объекта, откуда вы взяли эту информацию? 04.04.2011
  • @Bart: я видел это во время отладки. Список был массивом. После удаления было такое же количество элементов, но один был просто нулевым. 04.04.2011
  • @ user384706: Как вы сказали ниже, вы говорите о внутренностях ArrayList. Это компромисс эффективности, который делает реализация ArrayList, вместо перераспределения нового массива или итерации по массиву и смещению элементов, он просто изменяет значение первого указателя элемента и значение размера массива. То, как это работает извне, не изменилось (другие реализации JVM могут делать это по-другому). Зачем тебе здесь внутренности? Вы всегда можете вызвать .toArray(), чтобы получить массив правильного размера. 04.04.2011
  • @Tony: Меня не волнует внутреннее устройство. Я использовал его, я удалил элемент, а затем во время цикла for, потому что я не проверял нулевой указатель, код разбился. В этот момент я не думал, что в допустимый список , после удаления объекта, если я зацикливаюсь, я также должен проверить нулевое значение 04.04.2011
  • @Tony: Позвонить toArray()? Это хорошая идея. Можно опубликовать как ответ 05.04.2011
  • На самом деле перебирать коллекцию, которая является Iterable, довольно плохой стиль программирования. Вы должны либо выполнять итерацию с использованием объекта итератора, либо использовать альтернативный синтаксис, подобный этому for(Object x: varWithCollection){ dosomething.. with the var x} 05.04.2011
  • @ITroubs: я зацикливался с помощью итератора и наткнулся на это 05.04.2011
  • @user384706 user384706 я сомневаюсь, что вы использовали объект Iterator 05.04.2011
  • Я отредактировал свой ответ с примером того, как использовать итератор. 05.04.2011
  • @user: покажите нам SSCCE, демонстрирующий проблему, с которой вы столкнулись, и мы сможем объяснить, что происходит. 05.04.2011

Ответы:


1

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

04.04.2011

2

Согласно Java API здесь говорится, что функция удаления списка ДЕЙСТВИТЕЛЬНО сдвигает

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

РЕДАКТИРОВАТЬ:

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

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());
        }
    }
}

Класс А:

public class A {
    private String str;

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

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

}

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

04.04.2011
  • Вы не правы. Это упоминается только в апи E remove(int index);. Я говорю о remove(Object o) 04.04.2011
  • скачать .oracle.com/javase/1.5.0/docs/api/java/util/ прочитайте его. он даже не упоминает об индексации. реализация должна удалить первое вхождение, если оно существует, и, таким образом, уменьшить размер. вы можете закончить с тем же размером после вызова remove(Object o), НО только если o НЕ содержится в списке, поэтому независимо от того, содержится он или нет после вызова этой функции, у вас будет на один элемент o меньше. 05.04.2011
  • Я видел ссылку. Часть в вашем сообщении взята из документа API remove(int index) download.oracle.com/javase/1.5.0/docs/api/java/util/. Я не уверен, что вы имеете в виду, если o НЕ содержится в списке. Если это не так, ничего не удаляется. 05.04.2011

  • 3

    Если вы посмотрите на Реализация удаления 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, что является доказательством того, что вы получаете целый новый список свежих объектов, а не нуль, заполненный между ними. Это доказательство?

    06.05.2014

    4

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

    04.04.2011
  • Нет, ArrayList определенно сдвигает все более высокие элементы влево (поэтому удаление в начале списка относительно дорого). 05.04.2011
  • и поэтому выполнение list.remove(0) list.size() раз очистит весь список. 05.04.2011

  • 5

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

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

    02.03.2016

    6

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

    04.04.2011
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..