Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a Guava equivalent to Apache Commons CircularFifoBuffer?

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?

like image 885
Etienne Neveu Avatar asked Jan 09 '13 09:01

Etienne Neveu


3 Answers

Starting Guava 15.0 - you can use EvictingQueue

like image 142
MosheElisha Avatar answered Oct 14 '22 04:10

MosheElisha


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?

like image 44
Frank Pavageau Avatar answered Oct 14 '22 02:10

Frank Pavageau


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]
like image 2
Xaerxess Avatar answered Oct 14 '22 02:10

Xaerxess