19

我需要一种数据结构,它可以按 FIFO 顺序有效地缓冲特定数量的元素。

正如这个问题中提到的,Apache Commons 有一个 CircularFifoBuffer,但遗憾的是它没有被通用化。存在一些 分叉,但我不确定它们的维护状态。

由于 Guava 是满足我收藏需求的首选图书馆,我想知道:Guava 有没有好的替代品?如果没有,我是否应该在我的项目中实现它,基于 Apache Commons 的 CircularFifoBuffer?

4

4 回答 4

30

启动 Guava 15.0 - 您可以使用EvictingQueue

于 2013-05-06T07:41:57.980 回答
7

我在 Guava 中没有看到类似的东西,但是ForwardingQueue围绕一个ArrayDeque你检查容量的地方如何add()offer()等等。remove()如果它已经满了旧条目呢?

于 2013-01-09T10:28:43.597 回答
2

如果您想将 Apache Collections 与泛型一起使用(并且它包含工作类) ,那么带有泛型的 Commons-Collectionsmaven 链接)是一种方法。CircularFifoBuffer<E>

另一方面,正如@FrankPavageau 所说,您可以使用自己的ForwardingQueue实现。一种天真的方法(有进一步优化的地方)将是这样的:

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);
  }

}

用法:

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]
于 2013-01-09T11:44:30.497 回答
-2

JavaArrayBlockingQueue提供了一个固定大小的循环缓冲区。

于 2013-01-09T10:32:56.307 回答