我需要向ArrayList队列添加元素,但当我调用函数添加一个元素时,我希望它在数组的开头添加元素(因此它有最低的索引),如果数组有10个元素,添加一个新的结果是删除最古老的元素(具有最高索引的元素)。

有人有什么建议吗?


当前回答

List有add(int, E)方法,所以你可以使用:

list.add(0, yourObject);

然后你可以删除最后一个元素:

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

但是,您可能需要重新考虑您的需求或使用不同的数据结构,如Queue

EDIT

也许可以看看Apache的CircularFifoQueue:

CircularFifoQueue是一个先进先出队列,具有固定大小,如果已满则替换其最老的元素。

用你的最大大小初始化它:

CircularFifoQueue queue = new CircularFifoQueue(10);

其他回答

你可以看一下add(int index, E element):

将指定元素插入到此列表中的指定位置。 移动当前位于该位置(如果有)的元素 右边的后续元素(给它们的下标加1)。

一旦你添加了数组列表,你就可以检查数组列表的大小,并删除末尾的数组列表。

使用特定的数据结构

有各种各样的数据结构经过优化,可以在第一个索引处添加元素。请注意,如果您将您的集合转换为其中之一,对话可能需要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),所以只适用于非常小的列表。

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

您所描述的是使用Queue的合适情况。

因为你想添加新的元素,并删除旧的。你可以在结尾添加,也可以从开头删除。那不会有太大区别。

Queue有add(e)和remove()方法,它们分别在结尾添加新元素,并从开头删除旧元素。

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

因此,每次向队列添加元素时,都可以使用remove方法调用将其备份。


更新:

如果你想修复队列的大小,那么你可以看看:- ApacheCommons#CircularFifoBuffer

来自文档:-

CircularFifoBuffer是一个固定大小的先进先出缓冲区 如果已满,则替换最老的元素。

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

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

如您所见,当达到最大大小时,添加新元素将自动删除插入的第一个元素。

我认为实现应该很简单,但是考虑到效率,你应该使用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);
        }
    }
}