Java中的PriorityBlockingQueue comparator()方法

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可以提高代码效率和可读性,同时也能优化多线程环境下的元素管理问题。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程