原文: https://www.programiz.com/java-programming/priorityqueue

在本教程中,我们将借助示例学习 Java 集合框架的PriorityQueue类。

PriorityQueue类提供堆数据结构的功能。

它实现了Queue接口

Java `PriorityQueue` - 图1

与普通队列不同,优先级队列元素是按排序顺序检索的。

假设我们要按升序检索元素。 在这种情况下,优先级队列的头部将是最小的元素。 一旦检索到此元素,下一个最小的元素将是队列的开头。

重要的是要注意,优先级队列的元素可能未排序。 但是,元素总是按排序顺序检索。


创建PriorityQueue

为了创建优先级队列,我们必须导入java.util.PriorityQueue包。 导入包后,可以使用以下方法在 Java 中创建优先级队列。

  1. PriorityQueue<Integer> numbers = new PriorityQueue<>();

在这里,我们创建了一个没有任何参数的优先级队列。 在这种情况下,优先级队列的头部是队列的最小元素。 并且元素以升序从队列中删除。

但是,我们可以在Comparator接口的帮助下自定义元素的顺序。 我们将在本教程的后面部分中对此进行了解。


PriorityQueue方法

PriorityQueue类提供Queue接口中存在的所有方法的实现。


将元素插入PriorityQueue

  • add() - 将指定的元素插入队列。 如果队列已满,则会引发异常。
  • offer() - 将指定的元素插入队列。 如果队列已满,则返回false

例如,

  1. import java.util.PriorityQueue;
  2. class Main {
  3. public static void main(String[] args) {
  4. // Creating a priority queue
  5. PriorityQueue<Integer> numbers = new PriorityQueue<>();
  6. // Using the add() method
  7. numbers.add(4);
  8. numbers.add(2);
  9. System.out.println("PriorityQueue: " + numbers);
  10. // Using the offer() method
  11. numbers.offer(1);
  12. System.out.println("Updated PriorityQueue: " + numbers);
  13. }
  14. }

输出

  1. PriorityQueue: [2, 4]
  2. Updated PriorityQueue: [1, 4, 2]

在这里,我们创建了一个名为number的优先级队列。 我们已将 4 和 2 插入队列。

尽管在 2 之前插入了 4,但是队列的头是 2。这是因为优先级队列的头是队列的最小元素。

然后,我们将 1 插入队列。 现在重新排列了队列,以将最小的元素 1 存储到队列的开头。


访问PriorityQueue元素

要从优先级队列访问元素,我们可以使用peek()方法。 此方法返回队列的开头。 例如,

  1. import java.util.PriorityQueue;
  2. class Main {
  3. public static void main(String[] args) {
  4. // Creating a priority queue
  5. PriorityQueue<Integer> numbers = new PriorityQueue<>();
  6. numbers.add(4);
  7. numbers.add(2);
  8. numbers.add(1);
  9. System.out.println("PriorityQueue: " + numbers);
  10. // Using the peek() method
  11. int number = numbers.peek();
  12. System.out.println("Accessed Element: " + number);
  13. }
  14. }

输出

  1. PriorityQueue: [1, 4, 2]
  2. Accessed Element: 1

删除PriorityQueue元素

  • remove() - 从队列中删除指定的元素
  • poll() - 返回并删除队列的开头

例如:

  1. import java.util.PriorityQueue;
  2. class Main {
  3. public static void main(String[] args) {
  4. // Creating a priority queue
  5. PriorityQueue<Integer> numbers = new PriorityQueue<>();
  6. numbers.add(4);
  7. numbers.add(2);
  8. numbers.add(1);
  9. System.out.println("PriorityQueue: " + numbers);
  10. // Using the remove() method
  11. boolean result = numbers.remove(2);
  12. System.out.println("Is the element 2 removed? " + result);
  13. // Using the poll() method
  14. int number = numbers.poll();
  15. System.out.println("Removed Element Using poll(): " + number);
  16. }
  17. }

输出

  1. PriorityQueue: [1, 4, 2]
  2. Is the element 2 removed? true
  3. Removed Element Using poll(): 1

遍历PriorityQueue

要遍历优先级队列的元素,我们可以使用iterator()方法。 为了使用此方法,我们必须导入java.util.Iterator包。 例如,

  1. import java.util.PriorityQueue;
  2. import java.util.Iterator;
  3. class Main {
  4. public static void main(String[] args) {
  5. // Creating a priority queue
  6. PriorityQueue<Integer> numbers = new PriorityQueue<>();
  7. numbers.add(4);
  8. numbers.add(2);
  9. numbers.add(1);
  10. System.out.print("PriorityQueue using iterator(): ");
  11. //Using the iterator() method
  12. Iterator<Integer> iterate = numbers.iterator();
  13. while(iterate.hasNext()) {
  14. System.out.print(iterate.next());
  15. System.out.print(", ");
  16. }
  17. }
  18. }

输出

  1. PriorityQueue using iterator(): 1, 4, 2,

其他PriorityQueue方法

方法 内容描述
contains(element) 在优先级队列中搜索指定的元素。 如果找到该元素,则返回true,否则返回false
size() 返回优先级队列的长度。
toArray() 将优先级队列转换为数组并返回它。

PriorityQueue比较器

在以上所有示例中,优先级队列元素都是按自然顺序(升序)检索的。 但是,我们可以自定义此排序。

为此,我们需要创建自己的比较器类来实现Comparator接口。 例如,

  1. import java.util.PriorityQueue;
  2. import java.util.Comparator;
  3. class Main {
  4. public static void main(String[] args) {
  5. // Creating a priority queue
  6. PriorityQueue<Integer> numbers = new PriorityQueue<>(new CustomComparator());
  7. numbers.add(4);
  8. numbers.add(2);
  9. numbers.add(1);
  10. numbers.add(3);
  11. System.out.print("PriorityQueue: " + numbers);
  12. }
  13. }
  14. class CustomComparator implements Comparator<Integer> {
  15. @Override
  16. public int compare(Integer number1, Integer number2) {
  17. int value = number1.compareTo(number2);
  18. // elements are sorted in reverse order
  19. if (value > 0) {
  20. return -1;
  21. }
  22. else if (value < 0) {
  23. return 1;
  24. }
  25. else {
  26. return 0;
  27. }
  28. }
  29. }

输出

  1. PriorityQueue: [4, 3, 1, 2]

在上面的示例中,我们创建了一个优先级队列,将CustomComparator类作为参数传递。

CustomComparator类实现Comparator接口。

然后,我们覆盖compare()方法。 现在,该方法使元素的头成为最大数量。

要了解有关比较器的更多信息,请访问 Java Comparator