1。概述

在本文中,我们将研究EvictingQueue,MinMaxPriorityQueue从番石榴库构造。的EvictingQueue是循环缓冲区概念的一个实现。的MinMaxPriorityQueue允许我们使用所提供的元素访问其最小和最大元素比较器。

2.EvictingQueue

让我们从构造开始——在构造队列实例时,我们需要提供最大队列大小作为参数。

元素添加新项时EvictingQueue,队列满了,它会自动从它的头中删除一个元素

与标准队列行为相比,向全队列添加元素不会阻塞,而是删除头元素并向尾部添加新项。

我们可以想象EvictingQueue作为一个环,以只追加的方式插入元素。如果想在某个位置上添加新元素,只需覆盖给定位置上的现有元素。

让我们构造一个实例EvictingQueue最大大小为10。接下来,我们将给它添加10个元素:

evictingQueue = evictingQueue .create(10);IntStream。范围(0,10).forEach (evictingQueue:添加);assert (evictingQueue) . containexactly (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

如果我们有标准队列实现,向完整队列中添加一个新项将阻塞生产者。

这不是一个案例EvictingQueue实现。向它添加一个新元素将导致头部被移除,而新元素将被添加到尾部:

evictingQueue.add (100);assert (evictingQueue) . containexactly (1, 2, 3, 4, 5, 6, 7, 8, 9, 100);

通过使用EvictingQueue作为循环缓冲区,我们可以创建非常高效的并发程序。

3.MinMaxPriorityQueue

MinMaxPriorityQueue提供对最小和最大元素的常量时间访问。

为了得到最小的元素,我们需要调用peekFirst ()方法。为了得到最大的元素peekLast ()方法。注意,它们不会从队列中删除元素,只会检索元素。

元素的排序是由比较器需要传递给这个队列的构造函数。

假设有aCustomClass类有价值整数类型的字段:

类CustomClass{私有整数值;//标准构造函数,getter和setter}

让我们创建一个MinMaxPriorityQueue这将使用比较器int类型。接下来,我们将添加10个对象CustomClass输入队列:

MinMaxPriorityQueue queue = MinMaxPriorityQueue .orderedBy(Comparator.comparing(CustomClass::getValue)) .maximumSize(10) .create();IntStream .iterate(10, i -> i - 1) .limit(10) . foreach (i -> queue. foreach (i -> queue. foreach));添加(新CustomClass(我)));

由于其特点MinMaxPriorityQueue并通过比较器,队列头部的元素将等于1,队列尾部的元素将等于10:

为了(queue.peekFirst () .getValue ()) .isEqualTo (1);为了(queue.peekLast () .getValue ()) .isEqualTo (10);

因为我们的队列的容量是10,并且我们添加了10个元素,所以队列已经满了。向它添加新元素将导致删除队列中的最后一个元素。让我们添加一个CustomClass价值1:

队列中。添加(新CustomClass (1));

在此操作之后,队列中的最后一个元素将被删除,并且它尾部的新项将等于9。新的头将是-1,因为这是新的最小元素根据比较器在构造队列时传递的:

为了(queue.peekFirst () .getValue ()) .isEqualTo (1);为了(queue.peekLast () .getValue ()) .isEqualTo (9);

根据规范MinMaxPriorityQueue,在队列满的情况下,添加一个大于当前最大元素的元素将删除相同的元素——实际上是忽略它。

让我们添加一个100的数字,并测试该项目是否在该操作后的队列中:

队列中。添加(新CustomClass (100));为了(queue.peekFirst () .getValue ()) .isEqualTo (1);为了(queue.peekLast () .getValue ()) .isEqualTo (9);

正如我们看到的,队列中的第一个元素仍然等于-1,最后一个元素仍然等于9。因此,添加一个整数被忽略,因为它大于队列中已经最大的元素。

4.结论

在本文中,我们看了一下EvictingQueueMinMaxPriorityQueue从番石榴库构建。

我们看到了如何使用EvictingQueue作为循环缓冲区实现非常高效的程序。

我们使用了MinMaxPriorityQueue结合比较器以恒定时间访问最小和最大元素。

记住这两个显示的队列的特征是很重要的,因为向它们添加新元素将覆盖队列中已经存在的元素。这与标准队列实现相反,在标准队列实现中向全队列添加新元素将阻塞生成线程或抛出异常。

所有这些示例和代码片段的实现可以在GitHub项目-这是一个Maven项目,所以它应该很容易导入和运行。

通用的底部

通过。开始使用Spring 5和Spring Boot 2学习的春天课程:

>>查看课程
本文评论关闭!