Is there a Guava equivalent to Apache Commons CircularFifoBuffer?

10,473

Solution 1

Starting Guava 15.0 - you can use EvictingQueue

Solution 2

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?

Solution 3

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]
Share:
10,473
Etienne Neveu
Author by

Etienne Neveu

Hi. I'm french. I love web development, fresh orange juice, good movies, awesome books, chill electronic music, Brazilian Jiu-Jitsu, snowboarding, and traveling. I hate the war over general-purpose computing, the NSA's overreach, and patent trolls. But I also love Android, Scala, Spring Boot, Guava, Clean Code™, and Effective Java™. Authors I really respect: Robert C. Martin (Uncle Bob) on clean code Joshua Bloch on java best practices and API design Martin Fowler on refactoring and architecture Brian Goetz on java concurrency Michal Zalewski on web app security

Updated on June 03, 2022

Comments

  • Etienne Neveu
    Etienne Neveu almost 2 years

    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?