JDK中的FIFO队列

时间:2019-06-19 11:14:21

标签: java collections

我想要一个具有FIFO的受限队列。因此,如果队列的最大大小超出限制,则将删除第一个元素。

具有Google集合的FIFO队列:

Queue<Integer> fifo = EvictingQueue.create(2); 
fifo.add(1); 
fifo.add(2); 
fifo.add(3); 
System.out.println(fifo);  // prints [2, 3]

具有apache集合的FIFO队列:

// FIFO-queue works with apache collections
Queue<Integer> fifo2 = new CircularFifoQueue<>(2);
fifo2.add(1);
fifo2.add(2);
fifo2.add(3);
System.out.println(fifo2); // prints [2, 3]

具有JDK集合的FIFO队列:

Queue<Integer> fifo3 = new ArrayBlockingQueue<>(2);
fifo3.offer(1);
fifo3.offer(2);
fifo3.offer(3);
System.out.println(fifo3); // prints [1, 2]

ArrayBlockingQueue不能用作FIFO,它仅在队列已满时停止插入元素。

是否有任何类似于EvictingQueueCircularFifoQueue的JDK FIFO队列?

如果JDK没有提供类似的内容,我应该选择哪一个:EvictingQueueCircularFifoQueue? 哪个实施更好?

(请不要提供fifo队列的示例实现,我想使用lib,最好仅使用JDK)

2 个答案:

答案 0 :(得分:2)

如果看到ArrayBlockingQueue的offer实现,则该行有一行,因此值3甚至不会附加到items数组。

if (count == items.length)
  return false;

因此您可以这样做:

static void append(Queue<Integer> fifo, int i) {
  if (!fifo.offer(i)) {
      fifo.poll();
      fifo.offer(i);
  }
}

// in main:
Queue<Integer> fifo3 = new ArrayBlockingQueue<>(2);
append(fifo3, 1);
append(fifo3, 2);
append(fifo3, 3);
System.out.println(fifo3); // prints [2, 3]

答案 1 :(得分:1)

JDK确实提供了FIFO队列,但是没有大小限制(因此没有循环队列),它是LinkedList类。

就像javadoc says about Queue interface

  

通常(但不一定)以FIFO(先进先出)的方式对元素进行排序。 [...] 无论使用什么顺序,队列的开头都是该元素,可以通过调用remove()或poll()来删除。在FIFO队列中,所有新元素都是插入队列的末尾。其他种类的队列可能使用不同的放置规则。 每个队列实现必须指定其排序属性。

LinkedList doc中我们知道add方法“将指定的元素附加到此列表的末尾”,因此调用add/offer将在元素的末尾插入一个元素排队,而remove/poll将从头开始获得一个元素。

因此,如果不需要固定大小的队列,则可以使用:

Queue<Type> q = new LinkedList<Type>();
q.add(elem1);
q.add(elem2);
q.add(elem3); // [elem1, elem2, elem3]
q.remove(); // [elem2, elem3]

否则,您可以只使用Robert实现。