Java中的PriorityBlockingQueue comparator()方法
在Java中,PriorityBlockingQueue
是一个线程安全的优先级队列,可用于多线程环境下的元素管理,其内部元素的添加和获取均采用优先级进行排序,使得元素的获取更为灵活和高效。而在PriorityBlockingQueue
中,comparator()
方法则允许我们自定义排序器,根据不同的排序条件对队列内的元素进行排序。
什么是PriorityBlockingQueue
PriorityBlockingQueue
是Java中提供的一种线程安全的属性优先级队列,它基于数组实现,并使用可重入锁(ReentrantLock
)来保证其线程安全性,该队列的特点是元素的添加和获取是按照优先级进行排序。
PriorityBlockingQueue<Integer> priorityQueue = new PriorityBlockingQueue<>();
priorityQueue.add(4);
priorityQueue.add(1);
priorityQueue.add(3);
priorityQueue.add(2);
// 输出:1 2 3 4
while(!priorityQueue.isEmpty()){
System.out.print(priorityQueue.poll() + " ");
}
上述代码使用PriorityBlockingQueue
实现了元素的添加和获取,通过add()方法添加有序数据后,通过poll()方法将队列元素逐一取出输出。
使用Comparator实现自定义排序
使用PriorityBlockingQueue
时,如果其默认的排序方式无法满足需求,我们可以通过实现Comparator
接口来构建自定义排序器,以实现对元素的自定义排序规则。Comparator
接口仅有一个方法compare(Object o1, Object o2)
,该方法返回类型为int,表示按照比较结果进行升序或降序排列。我们可以通过实现Comparator
接口的compare
方法来对元素进行自定义排序,示例代码如下:
class Student {
String name;
int age;
float score;
public Student(String name, int age, float score) {
this.name = name;
this.age = age;
this.score = score;
}
}
class AgeComparator implements Comparator<Student> {
public int compare(Student s1, Student s2) {
return s1.age - s2.age;
}
}
PriorityBlockingQueue<Student> queue = new PriorityBlockingQueue<>(new AgeComparator());
queue.put(new Student("Tom", 20, 95f));
queue.put(new Student("Jack", 19, 80f));
queue.put(new Student("Mike", 21, 70f));
// 输出:Jack(19), Mike(21), Tom(20)
while(!queue.isEmpty()) {
System.out.print(queue.poll().name + "(" + queue.peek().age+") ");
}
上述示例代码中,首先定义了Student
类,其中包含三个属性:姓名、年龄、分数。接着在代码中定义了一个AgeComparator
类,用于比较Student
对象的年龄大小。在使用PriorityBlockingQueue
时,将AgeComparator
对象作为构造参数传入,即可实现按照年龄大小对队列中的元素进行排序。最后,通过while循环将元素逐一取出,并输出按照年龄大小排列的学生名字。
Comparator的另一种写法
除了上述的实现Comparator
接口的方式,我们还可以在实例化PriorityBlockingQueue
时直接使用匿名内部类来实现Comparator
接口,节省代码量,提高代码的可读性。示例代码如下:
PriorityBlockingQueue<Student> queue = new PriorityBlockingQueue<>(new Comparator<Student>() {
public int compare(Student s1, Student s2) {
return Float.compare(s1.score, s2.score);
}
});
queue.put(new Student("Tom", 20, 95f));
queue.put(new Student("Jack", 19, 80f));
queue.put(new Student("Mike", 21, 70f));
// 输出:Mike(21), Jack(19), Tom(20)
while(!queue.isEmpty()) {
System.out.print(queue.poll().name + "(" + queue.peek().age+") ");
}
上述代码中,使用了一个匿名内部类来实现Comparator
接口,同时通过Float.compare()
方法实现对元素分数的自定义排序比较。最后,通过while循环将元素逐一取出,并输出按照分数大小排列的学生名字。
结论
在Java中,PriorityBlockingQueue
提供了默认的优先级队列排序规则,同时也允许我们在使用时通过自定义Comparator
接口实现对元素的自定义排序。无论使用默认排序规则或是自定义排序规则,适当的使用PriorityBlockingQueue
可以提高代码效率和可读性,同时也能优化多线程环境下的元素管理问题。