Java ArrayList如何在开头添加元素
Posted
技术标签:
【中文标题】Java ArrayList如何在开头添加元素【英文标题】:Java ArrayList how to add elements at the beginning 【发布时间】:2012-10-08 14:50:27 【问题描述】:我需要将元素添加到 ArrayList
队列中,但是当我调用函数添加元素时,我希望它在数组的开头添加元素(因此它具有最低索引),如果该数组有 10 个元素,添加一个新元素会删除最旧的元素(索引最高的元素)。
有人有什么建议吗?
【问题讨论】:
你的意思是像remove
和add
吗?
你在用arraylist stack queue whatever
做什么最好避免添加到数组的开头,听起来你应该使用不同的集合。
首先,您应该自己制作一些东西。到目前为止你做了什么?
【参考方案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);
【讨论】:
我不会碰任何 10 英尺杆的 apache 库,尤其是因为存在 guava 的集合类。 Guava 的 EvictingQueue 在这里可能是一个不错的选择。【参考方案2】:使用特定的数据结构
有多种数据结构针对在第一个索引处添加元素进行了优化。不过请注意,如果您将收藏转换为其中之一,对话可能需要O(n)
的时间和空间复杂度
双端队列
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);
If you use Java 8 streams, this answer might interest you.
分析
时间复杂度:O(n)
空间复杂度:O(1)
看看JDK implementation,它的时间复杂度为O(n)
,所以只适用于非常小的列表。
【讨论】:
反转列表两次。与上述公认的解决方案相比,它会大大增加算法的运行时间吗? 它增加了 2n,所以是的,但是如果你有 【参考方案3】:你可以看看add(int index, E element):
在此列表中的指定位置插入指定元素。 移动当前在该位置的元素(如果有)和任何 右侧的后续元素(将其索引加一)。
添加后,您可以检查 ArrayList 的大小并删除最后的大小。
【讨论】:
【参考方案4】:你可能想看看 Deque。它使您可以直接访问列表中的第一项和最后一项。
【讨论】:
我很惊讶你是谈论 Deque 的唯一答案,这显然是最好的最佳解决方案。【参考方案5】:您所描述的是使用Queue
的合适情况。
既然你想add
新元素和remove
旧元素。您可以在末尾添加,从开头删除。这不会有太大的不同。
Queue 有 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】:我认为实现应该很简单,但考虑到效率,你应该使用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);
【讨论】:
【参考方案7】:Java LinkedList 提供了 addFirst(E e) 和 push(E e) 方法,可以将元素添加到列表的前面。
https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html#addFirst(E)
【讨论】:
【参考方案8】:你可以使用列表方法,删除和添加
list.add(lowestIndex, element);
list.remove(highestIndex, element);
【讨论】:
【参考方案9】:您可以使用此代码
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);
【讨论】:
【参考方案10】:你可以使用
public List<E> addToListStart(List<E> list, E obj)
list.add(0,obj);
return (List<E>)list;
用你的数据类型改变 E
如果需要删除最旧的元素,则可以添加:
list.remove(list.size()-1);
return 语句之前。否则 list 将在开头添加您的对象并保留最旧的元素。
这将删除列表中的最后一个元素。
【讨论】:
【参考方案11】:import java.util.*:
public class Logic
List<String> list = new ArrayList<String>();
public static void main(String...args)
Scanner input = new Scanner(System.in);
Logic obj = new Logic();
for (int i=0;i<=20;i++)
String string = input.nextLine();
obj.myLogic(string);
obj.printList();
public void myLogic(String strObj)
if (this.list.size()>=10)
this.list.remove(this.list.size()-1);
else
list.add(strObj);
public void printList()
System.out.print(this.list);
【讨论】:
【参考方案12】:import com.google.common.collect.Lists;
import java.util.List;
/**
* @author Ciccotta Andrea on 06/11/2020.
*/
public class CollectionUtils
/**
* It models the prepend O(1), used against the common append/add O(n)
* @param head first element of the list
* @param body rest of the elements of the list
* @return new list (with different memory-reference) made by [head, ...body]
*/
public static <E> List<Object> prepend(final E head, List<E> final body)
return Lists.asList(head, body.toArray());
/**
* it models the typed version of prepend(E head, List<E> body)
* @param type the array into which the elements of this list are to be stored
*/
public static <E> List<E> prepend(final E head, List<E> body, final E[] type)
return Lists.asList(head, body.toArray(type));
【讨论】:
【参考方案13】:我有一个类似的问题,试图在现有数组的开头添加一个元素,将现有元素向右移动并丢弃最旧的元素(数组 [length-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
祝你好运
【讨论】:
【参考方案14】:举个例子:-
List<String> element1 = new ArrayList<>();
element1.add("two");
element1.add("three");
List<String> element2 = new ArrayList<>();
element2.add("one");
element2.addAll(element1);
【讨论】:
以上是关于Java ArrayList如何在开头添加元素的主要内容,如果未能解决你的问题,请参考以下文章