PriorityQueue 略解

tech2026-03-10  1

PriorityQueue 一个基于优先级的无界优先级队列。优先级队列的元素按照其自然顺序进行排序,或者根据构造队列时提供的 Comparator 进行排序,可自定义排序方法。该队列不允许使用 null 元素也不允许插入不可比较的对象。(没有实现Comparable接口的对象)。 

package com.example.demo; import com.example.demo.pojo.User; import java.util.Comparator; import java.util.PriorityQueue; /** * @auther WHW * @date 2020/9/4 13:59 */ public class priorityQueueTest { public static void main(String[] args) { PriorityQueue<String> pqString = new PriorityQueue<String>(); //入列 pqString.offer("1"); pqString.offer("2"); pqString.offer("5"); pqString.offer("3"); pqString.offer("4"); //出列 System.out.print(pqString.poll()); //1 System.out.print(pqString.poll()); //2 System.out.print(pqString.poll()); //3 System.out.print(pqString.poll()); //4 System.out.println(pqString.poll()); //5 System.out.println("********************"); User u1 = new User((Integer)1, "kobe1" ,"123456"); User u2 = new User((Integer)2, "kobe2" , "123456"); User u3 = new User((Integer)3, "kobe3" ,"123456"); User u31 = new User((Integer)31, "kobe31" , "1"); User u32 = new User((Integer)32, "kobe32" , "2"); User u33 = new User((Integer)33, "kobe33" ,"3"); PriorityQueue<User> pqUser = new PriorityQueue<User>(new Comparator<User>() { @Override public int compare(User o1, User o2) { return o1.getId().compareTo(o2.getId()) * -1; } } ); //入列 pqUser.offer(u33); pqUser.offer(u1); pqUser.offer(u3); pqUser.offer(u2); pqUser.offer(u31); pqUser.offer(u32); //出列 System.out.println(pqUser.poll()); //1 System.out.println(pqUser.poll()); //2 System.out.println(pqUser.poll()); //3 System.out.println(pqUser.poll()); //4 System.out.println(pqUser.poll()); //5 System.out.println(pqUser.poll()); //6 } }

如上,直接不可比较的对象,我们重写 compare方法就好了。输出结果如下:

PriorityQueue是无界(可自动扩容)的,线程不安全的队列。 PriorityQueue是拥有优先级的队列。 PriorityQueue存储的元素要求必须是可比较的对象, 如果不是就必须明确指定比较器

什么是不可比较的对象呢?比如

Map<String,String> map1 = new HashMap<>(); map1.put("key1","value1"); map1.put("key2","value2"); Map<String,String> map2 = new HashMap<>(); map2.put("key1","value1"); map2.put("key2","value2"); Map<String,String> map3 = new HashMap<>(); map3.put("key1","value1"); map3.put("key2","value2"); PriorityQueue<Map> pqMap = new PriorityQueue<Map>(); //入列 pqMap.offer(map1); pqMap.offer(map2); pqMap.offer(map3); //出列 System.out.println(pqMap.poll()); //1 System.out.println(pqMap.poll()); //2 System.out.println(pqMap.poll()); //3

 Exception in thread "main" java.lang.ClassCastException: java.util.HashMap cannot be cast to java.lang.Comparable     at java.util.PriorityQueue.siftUpComparable(PriorityQueue.java:653)     at java.util.PriorityQueue.siftUp(PriorityQueue.java:648)     at java.util.PriorityQueue.offer(PriorityQueue.java:345)     at com.example.demo.priorityQueueTest.main(priorityQueueTest.java:80)

那我们给他明确指定比较器:升序排列

Map<String,Integer> map1 = new HashMap<>(); map1.put("key1",11); map1.put("key2",12); Map<String,Integer> map2 = new HashMap<>(); map2.put("key1",21); map2.put("key2",22); Map<String,Integer> map3 = new HashMap<>(); map3.put("key1",31); map3.put("key2",32); PriorityQueue<Map> pqMap = new PriorityQueue<Map>(new Comparator<Map>() { @Override public int compare(Map o1, Map o2) { // if (o1.get("key1").equals(o2.get("key1"))) return 1; // return -1; return o1.get("key1").toString().compareTo(o2.get("key1").toString()); } }); //入列 pqMap.offer(map1); pqMap.offer(map3); pqMap.offer(map2); //出列 System.out.println(pqMap.poll()); //1 System.out.println(pqMap.poll()); //2 System.out.println(pqMap.poll()); //3

看下结果:

排列成功。  

再看看这种。 

Map<String,Integer> map1 = new HashMap<>(); map1.put("key1",11); map1.put("key2",12); Map<String,Integer> map2 = new HashMap<>(); map2.put("key1",21); map2.put("key2",22); Map<String,Integer> map3 = new HashMap<>(); map3.put("key1",31); map3.put("key2",32); Map<String,Integer> map4 = new HashMap<>(); map4.put("key1",41); map4.put("key2",42); PriorityQueue<Map> pqMap = new PriorityQueue<Map>(new Comparator<Map>() { @Override public int compare(Map o1, Map o2) { if (o1.get("key1").equals(o2.get("key1"))) return 1; return -1; // return o1.get("key1").toString().compareTo(o2.get("key1").toString()); } }); //入列 pqMap.offer(map1); pqMap.offer(map3); pqMap.offer(map2); pqMap.offer(map4); //出列 System.out.println(pqMap.poll()); //1 System.out.println(pqMap.poll()); //2 System.out.println(pqMap.poll()); //3 System.out.println(pqMap.poll()); //4 想象中,equals相等就升序,不相等就降序。结果

有输出,没报错,我瞎比较,他就瞎poll?

最新回复(0)