Java PriorityQueue PriorityBlockingQueue
2019獨角獸企業重金招聘Python工程師標準>>>
Java PriorityQueue && PriorityBlockingQueue
我們知道隊列是遵循先進先出(First-In-First-Out)模式的,但有些時候需要在隊列中基于優先級處理對象。舉個例子,比方說我們有一個每日交易時段生成股票報告的應用程序,需要處理大量數據并且花費很多處理時間。客戶向這個應用程序發送請求時,實際上就進入了隊列。我們需要首先處理優先客戶再處理普通用戶。在這種情況下,Java的PriorityQueue(優先隊列)會很有幫助。
PriorityQueue類在Java1.5中引入并作為 Java Collections Framework 的一部分。PriorityQueue是基于優先堆的一個無界隊列,這個優先隊列中的元素可以默認自然排序或者通過提供的Comparator(比較器)在隊列實例化的時排序。
優先隊列不允許空值,而且不支持non-comparable(不可比較)的對象,比如用戶自定義的類。優先隊列要求使用Java Comparable和Comparator接口給對象排序,并且在排序時會按照優先級處理其中的元素。
優先隊列的頭是基于自然排序或者Comparator排序的最小元素。如果有多個對象擁有同樣的排序,那么就可能隨機地取其中任意一個。當我們獲取隊列時,返回隊列的頭對象。
優先隊列的大小是不受限制的,但在創建時可以指定初始大小。當我們向優先隊列增加元素的時候,隊列大小會自動增加。
PriorityQueue是非線程安全的,所以Java提供了PriorityBlockingQueue(實現BlockingQueue接口)用于Java多線程環境。
我們有一個用戶類Customer,它沒有提供任何類型的排序。當我們用它建立優先隊列時,應該為其提供一個比較器對象。
Customer.java
package?com.journaldev.collections;public?class?Customer?{private?int?id;private?String?name;public?Customer(int?i,?String?n){this.id=i;this.name=n;}public?int?getId()?{return?id;}public?String?getName()?{return?name;}}我們使用Java隨機數生成隨機用戶對象。對于自然排序,我們使用Integer對象,這也是一個封裝過的Java對象。下面是最終的測試代碼,展示如何使用PriorityQueue:
PriorityQueueExample.java
package?com.journaldev.collections;import?java.util.Comparator; import?java.util.PriorityQueue; import?java.util.Queue; import?java.util.Random;public?class?PriorityQueueExample?{public?static?void?main(String[]?args)?{//優先隊列自然排序示例Queue<Integer>?integerPriorityQueue?=?new?PriorityQueue<>(7);Random?rand?=?new?Random();for(int?i=0;i<7;i++){integerPriorityQueue.add(new?Integer(rand.nextInt(100)));}for(int?i=0;i<7;i++){Integer?in?=?integerPriorityQueue.poll();System.out.println("Processing?Integer:"+in);}//優先隊列使用示例Queue<Customer>?customerPriorityQueue?=?new?PriorityQueue<>(7,?idComparator);addDataToQueue(customerPriorityQueue);pollDataFromQueue(customerPriorityQueue);}//匿名Comparator實現public?static?Comparator<Customer>?idComparator?=?new?Comparator<Customer>(){@Overridepublic?int?compare(Customer?c1,?Customer?c2)?{return?(int)?(c1.getId()?-?c2.getId());}};//用于往隊列增加數據的通用方法private?static?void?addDataToQueue(Queue<Customer>?customerPriorityQueue)?{Random?rand?=?new?Random();for(int?i=0;?i<7;?i++){int?id?=?rand.nextInt(100);customerPriorityQueue.add(new?Customer(id,?"Pankaj?"+id));}}//用于從隊列取數據的通用方法private?static?void?pollDataFromQueue(Queue<Customer>?customerPriorityQueue)?{while(true){Customer?cust?=?customerPriorityQueue.poll();if(cust?==?null)?break;System.out.println("Processing?Customer?with?ID="+cust.getId());}}}?
注意我用實現了Comparator接口的Java匿名類,并且實現了基于id的比較器。
當我運行以上測試程序時,我得到以下輸出:
Processing?Integer:9 Processing?Integer:16 Processing?Integer:18 Processing?Integer:25 Processing?Integer:33 Processing?Integer:75 Processing?Integer:77 Processing?Customer?with?ID=6 Processing?Customer?with?ID=20 Processing?Customer?with?ID=24 Processing?Customer?with?ID=28 Processing?Customer?with?ID=29 Processing?Customer?with?ID=82 Processing?Customer?with?ID=96?
從輸出結果可以清楚的看到,最小的元素在隊列的頭部因而最先被取出。如果不實現Comparator,在建立customerPriorityQueue時會拋出ClassCastException。
Exception?in?thread?"main"?java.lang.ClassCastException:?com.journaldev.collections.Customer?cannot?be?cast?to?java.lang.Comparableat?java.util.PriorityQueue.siftUpComparable(PriorityQueue.java:633)at?java.util.PriorityQueue.siftUp(PriorityQueue.java:629)at?java.util.PriorityQueue.offer(PriorityQueue.java:329)at?java.util.PriorityQueue.add(PriorityQueue.java:306)at?com.journaldev.collections.PriorityQueueExample.addDataToQueue(PriorityQueueExample.java:45)at?com.journaldev.collections.PriorityQueueExample.main(PriorityQueueExample.java:25)==========END==========
轉載于:https://my.oschina.net/xinxingegeya/blog/366619
總結
以上是生活随笔為你收集整理的Java PriorityQueue PriorityBlockingQueue的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 个人阅读作业3
- 下一篇: 使用jvisualvm.exe 的Btr