优先队列的自然排序以及加入Comparator接口的实现
优先队列(PriorityQueue)的实现:
一,PriorityQueue的特性
- PriorityQueue是一种比较特殊的队列数据结构,传统的队列复合(FIFO)先进先出原则,而PriorityQueue是以数据的优先级进行存储;
- PriorityQueue类在Java1.5中引入并作为 Java Collections Framework 的一部分。PriorityQueue是基于优先堆的一个无界队列,这个优先队列中的元素可以默认自然排序或者通过提供的Comparator(比较器)在队列实例化的时排序。
- 优先队列不允许空值,而且不支持non-comparable(不可比较)的对象,比如用户自定义的类。优先队列要求使用Java Comparable和Comparator接口给对象排序,并且在排序时会按照优先级处理其中的元素。
- 优先队列的头是基于自然排序或者Comparator排序的最小元素。如果有多个对象拥有同样的排序,那么就可能随机地取其中任意一个。当我们获取队列时,返回队列的头对象。
- 优先队列的大小是不受限制的,但在创建时可以指定初始大小。当我们向优先队列增加元素的时候,队列大小会自动增加。(默认初始大小为11)
- PriorityQueue是非线程安全的,所以Java提供了PriorityBlockingQueue(实现BlockingQueue接口)用于Java多线程环境。
- 因为堆是一颗完全二叉树,位置k节点的父节点的位置为k/2,而他的两个子节点从左到右为2k和2k+1,
使用PriorityQueue实现默认的自然排序和加入Comparator的比较器排序:
首先自定义一个Customer类,
package com.deng.entity;
public class Customer {
private String name;
private int id;
public Customer(String name, int id) {
super();
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public int getId() {
return id;
}
}
使用PriorityQueue进行测试:
package com.deng.queue;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
import com.deng.entity.Customer;
public class PriorityQueueExample {
public static void main(String[] args) {
//优先队列自然排序示例
Queue<Integer> integerPriorityQueue =new PriorityQueue<>(7);
Random random=new Random();//用于生成随机用户对象
for(int i=0;i<7;i++) {
integerPriorityQueue.add(new Integer(random.nextInt(100)));
}
for(int i=0;i<7;i++) {
Integer in = integerPriorityQueue.poll();
System.out.println("Processing Integrt:" + in);
}
//优先队列使用示例
Queue<Customer> customerPriorityQueue=new PriorityQueue<>(7,idComparator);
//向队列中添加数据
addDataToQueue(customerPriorityQueue);
//从队列中删除数据
pollDataFromQueue(customerPriorityQueue);
}
//匿名Comparator实现
public static Comparator<Customer> idComparator=new Comparator<Customer>() {
@Override
public int compare(Customer c1, Customer c2) {
return (int)(c2.getId()-c1.getId());
}
};
//用于往队列增加数据的通用方法
@SuppressWarnings("unused")
private static void addDataToQueue(Queue<Customer> customerPriorityQueue) {
Random random=new Random();
for(int i=0;i<7;i++) {
int id=random.nextInt(100);
customerPriorityQueue.add(new Customer("kevin" + id, id));
}
}
//用于从队列取数据的方法
@SuppressWarnings("unused")
private static void pollDataFromQueue(Queue<Customer> customerPriorityQueue) {
while(true) {
Customer customer=customerPriorityQueue.poll();
if(customer==null) break ;
System.out.println("Processing Customer with ID=" + customer.getId());
}
}
}
测试结果会发现,默认按照自然排序进行比较;对头元素小于节点数据;
而在加入Comparator接口之后,对头元素大于节点数据;