1.基本概念
优先级队列,根据元素的优先级进行排列和访问,相当于根据元素的优先级进行自动排列,不需要我们手动去写一个代码给它排序。
(1)创建一个队列
PriorityQueue<类型> priorityQueue = new PriorityQueue<>(按照何种优先级排列);
我们需要什么类型的队列,就可以在类型一处写上该类型名,以便创建出一个该类型的队列。优先级默认是 小顶堆 (Min Heap),从小到大排序,如果有其他的排列需求,我们需要通过Comparator.comparing(类型名::成员名)的形式去设置队列的优先级,这样就可以根据我们自己的要求去排列了,类型应与队列的类型相同,而成员名处则写出该队列按照哪个元素的大小顺序(从小到大)进行排列的成员名。
如果我们要按照大顶堆(Max Heap)排序,则要以Comparator.comparing(类型名::成名).reversed()的形式进行排列,我们通过使用 reversed() 方法反转比较顺序,从而达到大顶堆排序的目的。
根据类型的不同,书写形式有微小的区别,如下
- Comparator.comparing():用于创建一个基于对象属性的Comparator
- Comparator.comparingDouble():用于创建一个基于双精度浮点数属性的Comparator
- Comparator.comparingLong():用于创建一个基于长整型属性的Comparator
(2)操作队列
- 如果我们要向队列中添加元素,我们可以使用 add() 方法向队列中添加元素。
- 如果我们需要查看优先级最高的元素,有两个方法,分别是 poll() 、 peek() 方法,其中 poll() 方法是提取出优先级最高元素并且移除,而 peek() 方法则是只查看不移除。
- 如果我们需要查看队列是否为空,可以使用 isEmpty() 方法判断 。
- 如果我们想要知道队列的长度,可以使用 size() 方法获取队列长度。
2.代码示例
我们用学生成绩的高低举一个例子。
首先我们先写一个学生类
class Student {
private final String name;
private final int math;
private final int english;
private final int chinese;
public String getName() {
return name;
}
public int getMath() {
return math;
}
public int getEnglish() {
return english;
}
public int getChinese() {
return chinese;
}
public int getSum() {
return math + english + chinese;
}
public Student(String name, int math, int english, int chinese) {
this.name = name;
this.math = math;
this.english = english;
this.chinese = chinese;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", math=" + math +
", english=" + english +
", chinese=" + chinese +
'}';
}
}
然后编写一个主类
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
// 创建Student类的队列,按照总成绩的优先级排序
PriorityQueue<Student> students = new PriorityQueue<>(Comparator.comparing( Student :: getSum));
System.out.println("输入学生人数:");
int num = s.nextInt();
while( num > 0 ) {
System.out.println("输入学生信息:");
students.add( new Student( s.next(), s.nextInt(), s.nextInt(), s.nextInt()));
num--;
}
for( Student t : students) {
System.out.println(t);
}
}
}
我们创建了一个学生类的队列,并且按照学生的总成绩优先级排列。
3.代码综合
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
// 创建Student类的队列,按照总成绩的优先级排序
PriorityQueue<Student> students = new PriorityQueue<>(Comparator.comparing( Student :: getSum));
System.out.println("输入学生人数:");
int num = s.nextInt();
while( num > 0 ) {
System.out.println("输入学生信息:");
students.add( new Student( s.next(), s.nextInt(), s.nextInt(), s.nextInt()));
num--;
}
for( Student t : students) {
System.out.println(t);
}
}
}
class Student {
private final String name;
private final int math;
private final int english;
private final int chinese;
public String getName() {
return name;
}
public int getMath() {
return math;
}
public int getEnglish() {
return english;
}
public int getChinese() {
return chinese;
}
public int getSum() {
return math + english + chinese;
}
public Student(String name, int math, int english, int chinese) {
this.name = name;
this.math = math;
this.english = english;
this.chinese = chinese;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", math=" + math +
", english=" + english +
", chinese=" + chinese +
'}';
}
}