Массивы Java, как добавлять элементы в начале

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

Есть ли у кого-нибудь предложения?

Ответ 1

List имеет метод add(int, E), поэтому вы можете использовать:

list.add(0, yourObject);

Затем вы можете удалить последний элемент с помощью

if(list.size() > 10)
    list.remove(list.size() - 1);

Однако вы можете пересмотреть свои требования или использовать другую структуру данных, например Queue

ИЗМЕНИТЬ

Возможно, посмотрите Apache CircularFifoQueue:

CircularFifoQueue - это первая очередь в очереди с фиксированным размером, которая заменяет его самый старый элемент, если он заполнен.

Просто инициализируйте его максимальным размером:

CircularFifoQueue queue = new CircularFifoQueue(10);

Ответ 2

Использование конкретных структур данных

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

Deque

JDK включает структуру Deque, которая предлагает такие методы, как addFirst(e) и offerFirst(e)

Deque<String> deque = new LinkedList<>();
deque.add("two");
deque.add("one");
deque.addFirst("three");
//prints "three", "two", "one"

Анализ

Пространственная и временная сложность вставки с константой LinkedList (O(1)). См. Big-O cheatsheet.

Реверсирование списка

Очень простой, но неэффективный метод - использовать обратное:

 Collections.reverse(list);
 list.add(elementForTop);
 Collections.reverse(list);

Если вы используете потоки Java 8, этот ответ может вас заинтересовать.

Анализ

  • Сложность времени: O(n)
  • Космическая сложность: O(1)

Глядя на JDK-реализацию, это имеет временную сложность O(n), поэтому подходит только для очень маленьких списков.

Ответ 3

Вы можете посмотреть add (int index, элемент E):

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

После добавления вы можете проверить размер массива ArrayList и удалить его в конце.

Ответ 4

Вы можете посмотреть на Deque. он дает вам прямой доступ к первым и последним элементам в списке.

Ответ 5

То, что вы описываете, является подходящей ситуацией для использования Queue.

Поскольку вы хотите add новый элемент, а remove - старый. Вы можете добавить в конце и удалить с самого начала. Это не будет иметь большого значения.

В очереди есть методы add(e) и remove(), которые добавляют в конце новый элемент и соответственно удаляют старый элемент.

Queue<Integer> queue = new LinkedList<Integer>();
queue.add(5);
queue.add(6);
queue.remove();  // Remove 5

Итак, каждый раз, когда вы добавляете элемент в Queue, вы можете создать резервную копию с вызовом метода remove.


ОБНОВЛЕНИЕ: -

И если вы хотите, чтобы фиксировал размер Queue, вы можете посмотреть: - ApacheCommons#CircularFifoBuffer

Из documentation: -

CircularFifoBuffer является первым в первом буфере с фиксированным размером который заменяет его самый старый элемент, если он заполнен.

Buffer queue = new CircularFifoBuffer(2); // Max size

queue.add(5);
queue.add(6);
queue.add(7);  // Automatically removes the first element `5`

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

Ответ 6

вы можете использовать этот код

private List myList = new ArrayList();
private void addItemToList(Object obj){
    if(myList.size()<10){
      myList.add(0,obj);
    }else{
      myList.add(0,obj);
      myList.remove(10);
    }
}

Ответ 7

Я думаю, что реализация должна быть простой, но учитывая эффективность, вы должны использовать LinkedList, но не ArrayList в качестве контейнера. Вы можете обратиться к следующему коду:

import java.util.LinkedList;
import java.util.List;

public class DataContainer {

    private List<Integer> list;

    int length = 10;
    public void addDataToArrayList(int data){
        list.add(0, data);
        if(list.size()>10){
            list.remove(length);
        }
    }

    public static void main(String[] args) {
        DataContainer comp = new DataContainer();
        comp.list = new LinkedList<Integer>();

        int cycleCount = 100000000;

        for(int i = 0; i < cycleCount; i ++){
            comp.addDataToArrayList(i);
        }
    }
}

Ответ 8

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

public List<E> addToListStart(List<E> list, E obj){
list.add(0,obj);
return (List<E>)list;

}

Изменить E на ваш тип данных

Если удаление самого старого элемента необходимо, вы можете добавить:

list.remove(list.size()-1); 

перед возвратом. В противном случае список добавит ваш объект в начало, а также сохранит самый старый элемент.

Это приведет к удалению последнего элемента в списке.

Ответ 9

Вы можете использовать методы списка, удалить и добавить

list.add(lowestIndex, element);
list.remove(highestIndex, element);

Ответ 11

У меня была аналогичная проблема, пытаясь добавить элемент в начале существующего массива, сдвинуть существующие элементы вправо и отбросить самый старый (массив [длина-1]). Мое решение может быть не очень эффективным, но оно работает для моих целей.

 Method:

   updateArray (Element to insert)

     - for all the elements of the Array
       - start from the end and replace with the one on the left; 
     - Array [0] <- Element

Удачи.