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

有人有什么建议吗?


当前回答

我遇到了类似的问题,试图在现有数组的开头添加一个元素,将现有元素向右移动,并丢弃最古老的元素(数组[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

祝你好运

其他回答

使用特定的数据结构

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

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

您可以使用此代码

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

你可以使用

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将在开始时添加对象并保留最古老的元素。

这将删除列表中的最后一个元素。