Gre*_*Cat 185 java queue collections
关于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;
}
}
Run Code Online (Sandbox Code Playgroud)
据我所知,Java stdlibs中没有标准的实现,但可能是Apache Commons中的那个或类似的东西?
Asa*_*saf 160
Apache commons集合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]
Run Code Online (Sandbox Code Playgroud)
如果您使用的是较旧版本的Apache commons集合(3.x),则可以使用CircularFifoBuffer,它基本上是相同的,没有泛型.
更新:在支持泛型的commons集合版本4发布后更新的答案.
小智 87
番石榴现在有一个EvictingQueue,非阻塞队列试图将新元素添加到队列时自动从队列的头部逐出元件和它充满.
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]
Run Code Online (Sandbox Code Playgroud)
Ren*_*aud 11
我喜欢@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;
}
}
Run Code Online (Sandbox Code Playgroud)
我唯一知道空间有限的是 BlockingQueue 接口(例如由 ArrayBlockingQueue 类实现) - 但如果填充,它们不会删除第一个元素,而是阻止放置操作,直到空间空闲(由其他线程删除) )。
据我所知,您的微不足道的实现是获得这种行为的最简单方法。
使用组合不扩展(是的,我的意思是扩展,如在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
Run Code Online (Sandbox Code Playgroud)
一个更好的选择(基于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
}Run Code Online (Sandbox Code Playgroud)