企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### [优先级队列PriorityQueue](https://lingcoder.gitee.io/onjava8/#/book/12-Collections?id=%e4%bc%98%e5%85%88%e7%ba%a7%e9%98%9f%e5%88%97priorityqueue) 先进先出(FIFO)描述了最典型的*队列规则*(queuing discipline)。队列规则是指在给定队列中的一组元素的情况下,确定下一个弹出队列的元素的规则。先进先出声明的是下一个弹出的元素应该是等待时间最长的元素。 优先级队列声明下一个弹出的元素是最需要的元素(具有最高的优先级)。例如,在机场,当飞机临近起飞时,这架飞机的乘客可以在办理登机手续时排到队头。如果构建了一个消息传递系统,某些消息比其他消息更重要,应该尽快处理,而不管它们何时到达。在Java 5 中添加了**PriorityQueue**,以便自动实现这种行为。 当在**PriorityQueue**上调用`offer()`方法来插入一个对象时,该对象会在队列中被排序。\[^5\]默认的排序使用队列中对象的*自然顺序*(natural order),但是可以通过提供自己的**Comparator**来修改这个顺序。**PriorityQueue**确保在调用`peek()`,`poll()`或`remove()`方法时,获得的元素将是队列中优先级最高的元素。 让**PriorityQueue**与**Integer**,**String**和**Character**这样的内置类型一起工作易如反掌。在下面的示例中,第一组值与前一个示例中的随机值相同,可以看到它们从**PriorityQueue**中弹出的顺序与前一个示例不同: ~~~ // collections/PriorityQueueDemo.java import java.util.*; public class PriorityQueueDemo { public static void main(String[] args) { PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(); Random rand = new Random(47); for(int i = 0; i < 10; i++) priorityQueue.offer(rand.nextInt(i + 10)); QueueDemo.printQ(priorityQueue); List<Integer> ints = Arrays.asList(25, 22, 20, 18, 14, 9, 3, 1, 1, 2, 3, 9, 14, 18, 21, 23, 25); priorityQueue = new PriorityQueue<>(ints); QueueDemo.printQ(priorityQueue); priorityQueue = new PriorityQueue<>( ints.size(), Collections.reverseOrder()); priorityQueue.addAll(ints); QueueDemo.printQ(priorityQueue); String fact = "EDUCATION SHOULD ESCHEW OBFUSCATION"; List<String> strings = Arrays.asList(fact.split("")); PriorityQueue<String> stringPQ = new PriorityQueue<>(strings); QueueDemo.printQ(stringPQ); stringPQ = new PriorityQueue<>( strings.size(), Collections.reverseOrder()); stringPQ.addAll(strings); QueueDemo.printQ(stringPQ); Set<Character> charSet = new HashSet<>(); for(char c : fact.toCharArray()) charSet.add(c); // Autoboxing PriorityQueue<Character> characterPQ = new PriorityQueue<>(charSet); QueueDemo.printQ(characterPQ); } } /* Output: 0 1 1 1 1 1 3 5 8 14 1 1 2 3 3 9 9 14 14 18 18 20 21 22 23 25 25 25 25 23 22 21 20 18 18 14 14 9 9 3 3 2 1 1 A A B C C C D D E E E F H H I I L N N O O O O S S S T T U U U W W U U U T T S S S O O O O N N L I I H H F E E E D D C C C B A A A B C D E F H I L N O S T U W */ ~~~ **PriorityQueue**是允许重复的,最小的值具有最高的优先级(如果是**String**,空格也可以算作值,并且比字母的优先级高)。为了展示如何通过提供自己的**Comparator**对象来改变顺序,第三个对**PriorityQueue**构造器的调用,和第二个对**PriorityQueue**的调用使用了由`Collections.reverseOrder()`(Java 5 中新添加的)产生的反序的**Comparator**。 最后一部分添加了一个**HashSet**来消除重复的**Character**。 **Integer**,**String**和**Character**可以与**PriorityQueue**一起使用,因为这些类已经内置了自然排序。如果想在**PriorityQueue**中使用自己的类,则必须包含额外的功能以产生自然排序,或者必须提供自己的**Comparator**。在[附录:集合主题](https://lingcoder.gitee.io/onjava8/#/)中有一个更复杂的示例来演示这种情况。