📜  Java PriorityQueue

📅  最后修改于: 2020-09-26 15:20:11             🧑  作者: Mango

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

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

它实现了Queue接口。

Java PriorityQueue类实现Queue接口。

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

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

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


创建PriorityQueue

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

PriorityQueue numbers = new PriorityQueue<>();

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

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


PriorityQueue方法

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


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

例如,

import java.util.PriorityQueue;

class Main {
    public static void main(String[] args) {

        // Creating a priority queue
        PriorityQueue numbers = new PriorityQueue<>();

        // Using the add() method
        numbers.add(4);
        numbers.add(2);
        System.out.println("PriorityQueue: " + numbers);

        // Using the offer() method
        numbers.offer(1);
        System.out.println("Updated PriorityQueue: " + numbers);
    }
}

输出

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

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

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

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


访问PriorityQueue元素

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

import java.util.PriorityQueue;

class Main {
    public static void main(String[] args) {

        // Creating a priority queue
        PriorityQueue numbers = new PriorityQueue<>();
        numbers.add(4);
        numbers.add(2);
        numbers.add(1);
        System.out.println("PriorityQueue: " + numbers);

        // Using the peek() method
        int number = numbers.peek();
        System.out.println("Accessed Element: " + number);
    }
}

输出

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

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

例如,

import java.util.PriorityQueue;

class Main {
    public static void main(String[] args) {

        // Creating a priority queue
        PriorityQueue numbers = new PriorityQueue<>();
        numbers.add(4);
        numbers.add(2);
        numbers.add(1);
        System.out.println("PriorityQueue: " + numbers);

        // Using the remove() method
        boolean result = numbers.remove(2);
        System.out.println("Is the element 2 removed? " + result);

        // Using the poll() method
        int number = numbers.poll();
        System.out.println("Removed Element Using poll(): " + number);
    }
}

输出

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

遍历PriorityQueue

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

import java.util.PriorityQueue;
import java.util.Iterator;

class Main {
    public static void main(String[] args) {

        // Creating a priority queue
        PriorityQueue numbers = new PriorityQueue<>();
        numbers.add(4);
        numbers.add(2);
        numbers.add(1);
        System.out.print("PriorityQueue using iterator(): ");

        //Using the iterator() method
        Iterator iterate = numbers.iterator();
        while(iterate.hasNext()) {
            System.out.print(iterate.next());
            System.out.print(", ");
        }
    }
}

输出

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

其他PriorityQueue方法
Methods Descriptions
contains(element) Searches the priority queue for the specified element. If the element is found, it returns true, if not it returns false.
size() Returns the length of the priority queue.
toArray() Converts a priority queue to an array and returns it.

PriorityQueue比较器

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

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

import java.util.PriorityQueue;
import java.util.Comparator;
class Main {
    public static void main(String[] args) {

        // Creating a priority queue
        PriorityQueue numbers = new PriorityQueue<>(new CustomComparator());
        numbers.add(4);
        numbers.add(2);
        numbers.add(1);
        numbers.add(3);
        System.out.print("PriorityQueue: " + numbers);
    }
}

class CustomComparator implements Comparator {

    @Override
    public int compare(Integer number1, Integer number2) {
        int value =  number1.compareTo(number2);
        // elements are sorted in reverse order
        if (value > 0) {
            return -1;
        }
        else if (value < 0) {
            return 1;
        }
        else {
            return 0;
        }
    }
}

输出

PriorityQueue: [4, 3, 1, 2]

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

CustomComparator类实现Comparator接口。

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

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