列出最大元素

时间:2013-09-23 11:47:38

标签: java list arraylist

我想在java中创建一个列表,在添加新元素时,将检查是否达到了限制。如果是,请删除最旧的元素。

我正在考虑制作ArrayList的子节点并覆盖add(Object)。在那里我会做到:

if(size() + 1 > MAX)
    remove(get(0));
super.add(newObject);

有更好的方法吗?

6 个答案:

答案 0 :(得分:5)

这可能有很多解决方案,但我认为如果你做出一个改变,你的方法是合适的:你的底层实现类应该是LinkedList,而不是ArrayList。原因是,当您移除的值必须向上移动后,在remove每个元素上调用ArrayList时(使remove(0)成为最糟糕的情况!)。但是对于LinkedList来说这不是问题。

答案 1 :(得分:1)

您描述的是循环FIFO缓冲区。您可以使用Apache Commons-collections实现。

请参阅Commons CollectionsCircularFifoBuffer了解文档

答案 2 :(得分:0)

你可以按照你所描述的方式进行,但这样一个List的性能会很低。想象一下,已达到限制并删除第一个元素。这将涉及将一个索引向上复制基础数组的所有元素。然后将新元素添加到最后一个索引。特别是复制所有元素是昂贵的

或者你可以使用LinkedList,这对这类操作更有效。

另一种方法是编写自己的类来实现Circular Buffer。 这基本上是MAX的数组。您必须保留第一个元素的索引和数组中元素的数量。添加元素时,检查元素数是否等于MAX,如果是,则覆盖第一个元素并将第一个元素的索引增加1。 索引的getter和setter也需要考虑第一个元素的偏移量,但这并不过分复杂。

最佳选择取决于您的使用案例。如果您必须在列表中的随机位置执行大量插入和删除操作,LinkedList绝对是可行的方法。如果您只想在末尾添加项目并删除头部,则循环缓冲区非常有效。

答案 3 :(得分:0)

IMO,你应该使用带有列表包装器的数组。然后你可以随心所欲。您还可以添加方法,例如得到它返回一个List。

答案 4 :(得分:0)

您可以使用Deque

private final int LIMIT = 10;

private Deque<String> queue = new ArrayDeque<String>(LIMIT);

public void addToList(final String element) {
   Deque<String> queue = new ArrayDeque<String>(LIMIT);
   if (!queue.offer(element)) {
      queue.removeFirst();
      queue.offer(element);
   }
}

答案 5 :(得分:0)

创建自己的班级来完成这项工作。跟踪两个变量。一个表示零元素,一个表示下一个元素的位置。

public class MyList<T>
{
    private T array[];
    private int first;
    private int next;
    private int count;

    public MyList(int count)
    {
        array = new T[count];
    }

    public void add(T obj)
    {
        array[next++] = obj;
        next %= array.length;
        if (count == array.length)
        {
            zero = (zero + 1) % array.length;
        } else count++;
    }

    public T get(int index)
    {
        return array[(zero + index) % array.length];
    }
}