关于Java库的一个非常简单和快速的问题:是否有一个现成的类实现了一个具有固定最大大小的Queue——即它总是允许添加元素,但它会无声地删除头部元素以容纳新添加的元素。

当然,手动实现它很简单:

import java.util.LinkedList;

public class LimitedQueue<E> extends LinkedList<E> {
    private int limit;

    public LimitedQueue(int limit) {
        this.limit = limit;
    }

    @Override
    public boolean add(E o) {
        super.add(o);
        while (size() > limit) { super.remove(); }
        return true;
    }
}

据我所知,在Java stdlibs中没有标准的实现,但在Apache Commons或类似的东西中可能有一个?


当前回答

Guava现在有一个驱逐队列,这是一个非阻塞队列,当试图向队列中添加新元素时,它会自动从队列头部驱逐元素。

import java.util.Queue;
import com.google.common.collect.EvictingQueue;

Queue<Integer> fifo = EvictingQueue.create(2); 
fifo.add(1); 
fifo.add(2); 
fifo.add(3); 
System.out.println(fifo); 

// Observe the result: 
// [2, 3]

其他回答

Apache公共集合4有一个CircularFifoQueue<>,这就是你要找的。引用javadoc:

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

    import java.util.Queue;
    import org.apache.commons.collections4.queue.CircularFifoQueue;

    Queue<Integer> fifo = new CircularFifoQueue<Integer>(2);
    fifo.add(1);
    fifo.add(2);
    fifo.add(3);
    System.out.println(fifo);

    // Observe the result: 
    // [2, 3]

如果你使用的是Apache公共集合(3.x)的旧版本,你可以使用CircularFifoBuffer,它基本上是相同的东西,没有泛型。

更新:支持泛型的公共集合版本4发布后的更新答案。

Guava现在有一个驱逐队列,这是一个非阻塞队列,当试图向队列中添加新元素时,它会自动从队列头部驱逐元素。

import java.util.Queue;
import com.google.common.collect.EvictingQueue;

Queue<Integer> fifo = EvictingQueue.create(2); 
fifo.add(1); 
fifo.add(2); 
fifo.add(3); 
System.out.println(fifo); 

// Observe the result: 
// [2, 3]

你可以使用MinMaxPriorityQueue从谷歌Guava,从javadoc:

最小-最大优先级队列可以配置最大大小。如果是这样,每当队列的大小超过该值时,队列将根据其比较器(可能是刚刚添加的元素)自动删除其最大的元素。这与传统的有界队列不同,后者在新元素满时阻塞或拒绝新元素。

我喜欢@FractalizeR解决方案。但我还会保留并返回super.add(o)的值!

public class LimitedQueue<E> extends LinkedList<E> {

    private int limit;

    public LimitedQueue(int limit) {
        this.limit = limit;
    }

    @Override
    public boolean add(E o) {
        boolean added = super.add(o);
        while (added && size() > limit) {
           super.remove();
        }
        return added;
    }
}

LRUMap是另一种可能,同样来自Apache Commons。

http://commons.apache.org/collections/apidocs/org/apache/commons/collections/map/LRUMap.html