Java队列 PriorityQueue
轉載請標明出處:http://blog.csdn.net/zhaoyanjun6/article/details/120829314
 本文出自【趙彥軍的博客】
Java隊列 Queue
 Java隊列 Deque
 Java隊列 PriorityQueue
 Java棧 Stack
 Java阻塞隊列 LinkedBlockingDeque
文章目錄
- PriorityQueue
- 小結
PriorityQueue
我們知道,Queue是一個先進先出(FIFO)的隊列。
在銀行柜臺辦業務時,我們假設只有一個柜臺在辦理業務,但是辦理業務的人很多,怎么辦?
可以每個人先取一個號,例如:A1、A2、A3……然后,按照號碼順序依次辦理,實際上這就是一個Queue。
如果這時來了一個VIP客戶,他的號碼是V1,雖然當前排隊的是A10、A11、A12……但是柜臺下一個呼叫的客戶號碼卻是V1。
這個時候,我們發現,要實現“VIP插隊”的業務,用Queue就不行了,因為Queue會嚴格按FIFO的原則取出隊首元素。我們需要的是優先隊列:PriorityQueue。
PriorityQueue和Queue的區別在于,它的出隊順序與元素的優先級有關,對PriorityQueue調用remove()或poll()方法,返回的總是優先級最高的元素。
要使用PriorityQueue,我們就必須給每個元素定義“優先級”。我們以實際代碼為例,先看看PriorityQueue的行為:
public class Main {public static void main(String[] args) {Queue<String> q = new PriorityQueue<>();// 添加3個元素到隊列:q.offer("apple");q.offer("pear");q.offer("banana");System.out.println(q.poll()); // appleSystem.out.println(q.poll()); // bananaSystem.out.println(q.poll()); // pearSystem.out.println(q.poll()); // null,因為隊列為空} }我們放入的順序是"apple"、"pear"、"banana",但是取出的順序卻是"apple"、"banana"、"pear",這是因為從字符串的排序看,"apple"排在最前面,"pear"排在最后面。
因此,放入PriorityQueue的元素,必須實現Comparable接口,PriorityQueue會根據元素的排序順序決定出隊的優先級。
如果我們要放入的元素并沒有實現Comparable接口怎么辦?PriorityQueue允許我們提供一個Comparator對象來判斷兩個元素的順序。我們以銀行排隊業務為例,實現一個PriorityQueue:
public class Main {public static void main(String[] args) {Queue<User> q = new PriorityQueue<>(new UserComparator());// 添加3個元素到隊列:q.offer(new User("Bob", "A1"));q.offer(new User("Alice", "A2"));q.offer(new User("Boss", "V1"));System.out.println(q.poll()); // Boss/V1System.out.println(q.poll()); // Bob/A1System.out.println(q.poll()); // Alice/A2System.out.println(q.poll()); // null,因為隊列為空} }class UserComparator implements Comparator<User> {public int compare(User u1, User u2) {if (u1.number.charAt(0) == u2.number.charAt(0)) {// 如果兩人的號都是A開頭或者都是V開頭,比較號的大小:return u1.number.compareTo(u2.number);}if (u1.number.charAt(0) == 'V') {// u1的號碼是V開頭,優先級高:return -1;} else {return 1;}} }class User {public final String name;public final String number;public User(String name, String number) {this.name = name;this.number = number;}public String toString() {return name + "/" + number;} }實現PriorityQueue的關鍵在于提供的UserComparator對象,它負責比較兩個元素的大小(較小的在前)。UserComparator總是把V開頭的號碼優先返回,只有在開頭相同的時候,才比較號碼大小。
上面的UserComparator的比較邏輯其實還是有問題的,它會把A10排在A2的前面,請嘗試修復該錯誤。
小結
PriorityQueue實現了一個優先隊列:從隊首獲取元素時,總是獲取優先級最高的元素。
PriorityQueue默認按元素比較的順序排序(必須實現Comparable接口),也可以通過Comparator自定義排序算法(元素就不必實現Comparable接口)。
總結
以上是生活随笔為你收集整理的Java队列 PriorityQueue的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Java队列 Deque
- 下一篇: Java栈 Stack
