0

I want to have a limited queue with FIFO. So if maximum size of queue exceeds, first element(s) are removed.

FIFO queue with google collections:

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

FIFO queue with apache collections:

// 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]

FIFO queue with JDK collections:

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

ArrayBlockingQueue does not work as FIFO, it only stops inserting elements if queue is full.

Are there any JDK FIFO queues working similar to EvictingQueue or CircularFifoQueue?

And if JDK does not provide something like that, which one should I take: EvictingQueue or CircularFifoQueue? Which is better implemented?

(Please dont provide example implementation of fifo queues, I want to use lib, preferable only JDK)

Naman
  • 27,789
  • 26
  • 218
  • 353
nimo23
  • 5,170
  • 10
  • 46
  • 75

2 Answers2

2

If you see the ArrayBlockingQueue's offer implementation, it has a line, so value 3 is not even appended to the items array.

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

So you can do this:

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]
Robert Boros
  • 48
  • 1
  • 7
  • So it seems, JDK does not provide a queue implementation where first elements are removed automatically if size exceeds. The end result with your `append()`, the `CircularFifoQueue` and `EvictingQueue` is the same, still I dont know the pitfalls between those..all are bounded and blocking queues, so I guess, I will use your `append()`-method instead of the others..thanks! – nimo23 Jun 19 '19 at 12:00
1

JDK does provide a FIFO queue, but with no size limit (so no circular queue), and it's the LinkedList class.

Like the javadoc says about Queue interface:

Queues typically, but do not necessarily, order elements in a FIFO (first-in-first-out) manner. [...] Whatever the ordering used, the head of the queue is that element which would be removed by a call to remove() or poll(). In a FIFO queue, all new elements are inserted at the tail of the queue. Other kinds of queues may use different placement rules. Every Queue implementation must specify its ordering properties.

And from the LinkedList doc we know that the add method "appends the specified element to the end of this list", so calling add/offer will insert an element at the tail of the queue, while remove/poll will get an element from the head.

So, if you don't need a fixed size queue, you can use:

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

Otherwise, you can just use Robert implementation.

crissal
  • 2,547
  • 7
  • 25
  • Good to know, thanks. For my case, I need a bounded queue. However, it`s strange that no queue-implementations provide a method to get its tail (=the last element in the queue). – nimo23 Jun 19 '19 at 12:29
  • 1
    The Queue interface doesn't provide it, however LinkedList does. `remove()/poll()` will extract the element from the head, while `remove​(int index)` will extract an element from an arbitrary position; if you need to extract quickly the tail, you can use `pollLast()` – crissal Jun 19 '19 at 12:33
  • 1
    @nimo23 A FIFO/`Queue` clearly is a data structure which can only insert at one end and remove from the other. If you want a data structure which also allows to get the last element, you are looking for a [`Deque`](https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/Deque.html), which stands for “double ended queue”. When you follow the link, you’ll see that there are multiple implementations and I’d prefer `ArrayDeque` over `LinkedList`, especially as you know the intended capacity before-hand. When strictly enforcing the maximum size, it *is* a circular fifo queue. – Holger Jun 19 '19 at 14:16