1. 概述
本文我们将学习了解 Apache Commons Collections中提供的 CircularFifoQueue 数据结构。
CircularFifoQueue
2. Maven 依赖
首先添加Maven依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.1</version>
</dependency>
最新版本请查看 Maven 仓库.
3. 初始化-构造函数
使用默认构造函数,它创建一个默认大小为 32 的队列
CircularFifoQueue<String> bits = new CircularFifoQueue();
也可指定队列所需的最大大小:
CircularFifoQueue<String> colors = new CircularFifoQueue<>(5);
另外也可接受Collection作为构造函数参数来创建 CircularFifoQueue 对象。这种情况,队列将填充Collection的元素,并且其大小与集合的大小相同:
CircularFifoQueue<String> daysOfWeek = new CircularFifoQueue<>(days);
注意:由于这个队列在构造时已经满了,任何新增都会导致第一个创建的元素被丢弃。
4. 添加元素
与其他 Queue 接口实现一样,我们可以使用 add 和 offer 方法添加元素。Queue JavaDoc 指出 offer 方法应在操作容量限制的队列时使用。
然而,由于 CircularFifoQueue 是非阻塞的,插入操作不会失败。因此,它的 add 和 offer 方法表现出相同的行为。
让我们看看如何使用 add 方法向我们的 colors 队列添加元素:
colors.add("Red");
colors.add("Blue");
colors.add("Green");
以及如何使用 offer 添加:
colors.offer("White");
colors.offer("Black");
5. 查找和删除元素
5.1. Peek 方法
peek 返回队列的第一个元素。
只要在调用之间没有更改队列中的元素,此方法将始终返回相同的元素。如果队列为空,则 peek 方法将返回 null。
String colorsHead = colors.peek();
5.2. Element 方法
element 方法类似于 peek,区别是如果队列为空会抛出异常:
colorsHead = colors.element();
5.3. Get 方法
使用 get 方法传入索引,获取队列中指定位置元素:
String color = colors.get(1);
上面会返回 “Blue“。
现在让我们向队列中再添加三个元素,并再次检查这个结果:
colors.add("Orange");
colors.add("Violet");
colors.add("Pink");
color = colors.get(1);
这次,get 方法返回 "Black"。因为我们的队列大小限制为5,插入新元素时,前三个元素("Red"、"Blue"、"Green")被删除。
5.4. Poll 方法
poll 方法会移除队首元素并返回该元素。如果队列没有元素,则 poll 方法返回 null:
colorsHead = colors.poll();
5.5. Remove 方法
remove 方法与 poll 方法类似,它返回队列的头部元素并将返回的元素从队列中移除。但是,如果队列为空,remove 方法将抛出异常:
colorsHead = colors.remove();
5.6. Clear 方法
用于清空队列
colors.clear();
6. 状态检测
maxSize 方法返回队列的最大容量
int maxSize = bits.maxSize();
这里会返回 32,因为示例中的 bits 队列是使用默认构造函数创建的。
size 方法返回队列中实际元素数量:
int size = colors.size();
isEmpty 检查队列是否为空:
boolean isEmpty = bits.isEmpty();
isAtFullCapacity 检查队列是否已满:
boolean isFull = daysOfWeek.isAtFullCapacity();
需要注意的是,此方法仅在 4.1 版本及以上可用。
另一个我们可以用来检测队列是否已满的方法是 isFull 。但对于 CircularFifoQueue,isFull 方法将始终返回 false,因为队列始终可以接受新元素:
boolean isFull = daysOfWeek.isFull();
7. 总结
本文介绍了如何使用 Apache Commons 的 CircularFifoQueue。我们看了一些示例,说明了如何实例化队列对象、填充队列、清空队列、获取和删除队列中的元素以及检查队列的大小和容量。
最后完整代码可从 GitHub 上获取。