I need a data structure that can efficiently buffer a specific number of elements, in FIFO order.
As mentioned in this question, Apache Commons has a CircularFifoBuffer, but it is sadly not generified. Some forks exist, but I'm not sure of their maintenance status.
Since Guava is the go-to library for my collection needs, I'm wondering: is there a good alternative in Guava? If not, should I implement it in my project, based on Apache Commons' CircularFifoBuffer?
Starting Guava 15.0 - you can use EvictingQueue
I don't see anything like that in Guava, but how about a ForwardingQueue
built around an ArrayDeque
where you check the capacity on add()
, offer()
, etc. and remove()
old entries if it's already full?
Commons-Collections with Generics (maven link) is the way to go if you want to use Apache Collections with generics (and it contains working CircularFifoBuffer<E>
class).
On the other hand, as @FrankPavageau says, you can use your own ForwardingQueue
implementatation. A naive approach (with place for further optimizations) would be something like this:
static class BoundedQueue<E> extends ForwardingQueue<E> {
private final Queue<E> delegate;
private final int capacity;
public BoundedQueue(final int capacity) {
this.delegate =
new ArrayDeque<E>(capacity); // specifying initial capacity is optional
this.capacity = capacity;
}
@Override
protected Queue<E> delegate() {
return delegate;
}
@Override
public boolean add(final E element) {
if (size() >= capacity) {
delegate.poll();
}
return delegate.add(element);
}
@Override
public boolean addAll(final Collection<? extends E> collection) {
return standardAddAll(collection);
}
@Override
public boolean offer(final E o) {
return standardOffer(o);
}
}
Usage:
final BoundedQueue<Integer> boundedQueue = new BoundedQueue<Integer>(3);
boundedQueue.add(1);
System.out.println(boundedQueue); // [1]
boundedQueue.add(2);
System.out.println(boundedQueue); // [1, 2]
boundedQueue.add(3);
System.out.println(boundedQueue); // [1, 2, 3]
boundedQueue.add(4);
System.out.println(boundedQueue); // [2, 3, 4]
boundedQueue.addAll(Arrays.asList(5, 6, 7, 8));
System.out.println(boundedQueue); // [6, 7, 8]
((Queue<Integer>) boundedQueue).offer(9);
System.out.println(boundedQueue); // [7, 8, 9]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With