我需要向ArrayList队列添加元素,但当我调用函数添加一个元素时,我希望它在数组的开头添加元素(因此它有最低的索引),如果数组有10个元素,添加一个新的结果是删除最古老的元素(具有最高索引的元素)。
有人有什么建议吗?
我需要向ArrayList队列添加元素,但当我调用函数添加一个元素时,我希望它在数组的开头添加元素(因此它有最低的索引),如果数组有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将在开始时添加对象并保留最古老的元素。
这将删除列表中的最后一个元素。
其他回答
您可以使用此代码
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);
}
}
使用特定的数据结构
有各种各样的数据结构经过优化,可以在第一个索引处添加元素。请注意,如果您将您的集合转换为其中之一,对话可能需要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备忘单。
反转列表
一个非常简单但效率很低的方法是使用reverse:
Collections.reverse(list);
list.add(elementForTop);
Collections.reverse(list);
如果您使用Java 8流,这个答案可能会让您感兴趣。
分析
时间复杂度:O(n) 空间复杂度:O(1)
看看JDK的实现,它的时间复杂度是O(n),所以只适用于非常小的列表。
带FIFO规则的有界循环缓冲区
看来您需要一个容量有限的循环缓冲区。 您更喜欢类似数组的行为,而不喜欢链接队列。 我说的对吗? 您似乎需要将容量设置为“10”。 这可以通过有界结构实现。 你似乎也需要一个先进先出的纪律。
使用ArrayBlockingQueue的解决方案
一个由数组支持的有界阻塞队列…排序元素FIFO(先进先出)。队列的头是在队列上停留时间最长的元素。队列的尾部是在队列上停留时间最短的元素。在队列尾部插入新元素,队列检索操作获取队列头部的元素。 放,拿都挡。提议,投票不阻拦。
PriorityBlockingQueue
你可以看看PriorityBlockingQueue的文档。有一个类的例子,它“对可比元素应用先进先出的绑定打破”。
ArrayBlockingQueue的示例
ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
for (int i = 10; i < 30; i++) {
if (queue.remainingCapacity() > 0) {
queue.offer(i);
} else {
queue.poll();
queue.offer(i);
}
if (queue.size() > 9) {
System.out.println(queue);
}
}
你可以看一下add(int index, E element):
将指定元素插入到此列表中的指定位置。 移动当前位于该位置(如果有)的元素 右边的后续元素(给它们的下标加1)。
一旦你添加了数组列表,你就可以检查数组列表的大小,并删除末尾的数组列表。
举个例子:-
List<String> element1 = new ArrayList<>();
element1.add("two");
element1.add("three");
List<String> element2 = new ArrayList<>();
element2.add("one");
element2.addAll(element1);