Массивы 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);
Ответ 10
Java LinkedList предоставляет как метод addFirst (E e), так и метод push (E e), который добавляет элемент в начало списка.
https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html#addFirst(E)
Ответ 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
Удачи.