关于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或类似的东西中可能有一个?
使用组合而不是extends(是的,我指的是extends,就像在java中引用extends关键字一样,是的,这是继承)。复合更优越,因为它完全屏蔽了你的实现,允许你在不影响类的用户的情况下改变实现。
我建议尝试这样的东西(我直接在这个窗口中输入,所以买家要小心语法错误):
public LimitedSizeQueue implements Queue
{
private int maxSize;
private LinkedList storageArea;
public LimitedSizeQueue(final int maxSize)
{
this.maxSize = maxSize;
storageArea = new LinkedList();
}
public boolean offer(ElementType element)
{
if (storageArea.size() < maxSize)
{
storageArea.addFirst(element);
}
else
{
... remove last element;
storageArea.addFirst(element);
}
}
... the rest of this class
一个更好的选择(基于Asaf的回答)可能是用一个泛型类包装Apache Collections CircularFifoBuffer。例如:
public LimitedSizeQueue<ElementType> implements Queue<ElementType>
{
private int maxSize;
private CircularFifoBuffer storageArea;
public LimitedSizeQueue(final int maxSize)
{
if (maxSize > 0)
{
this.maxSize = maxSize;
storateArea = new CircularFifoBuffer(maxSize);
}
else
{
throw new IllegalArgumentException("blah blah blah");
}
}
... implement the Queue interface using the CircularFifoBuffer class
}
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发布后的更新答案。