Java優先佇列(PriorityQueue)示例
Java優先佇列(PriorityQueue)示例
本文由 ImportNew - ImportNew讀者 翻譯自 journaldev。如需轉載本文,請先參見文章末尾處的轉載要求。
文章由@Jaskey_Lam翻譯。如果你也希望參與類似的系列文章翻譯,可以加入我們的Java開發 和 技術翻譯 小組。
我們知道佇列是遵循先進先出(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
1 |
package com.journaldev.collections; |
2 |
3 |
public class Customer
{ |
4 |
5 |
private int id; |
6 |
private String
name; |
7 |
8 |
public Customer( int i,
String n){ |
9 |
this .id=i; |
10 |
this .name=n; |
11 |
} |
12 |
13 |
public int getId()
{ |
14 |
return id; |
15 |
} |
16 |
17 |
public String
getName() { |
18 |
return name; |
19 |
} |
20 |
21 |
} |
我們使用Java隨機數生成隨機使用者物件。對於自然排序,我們使用Integer物件,這也是一個封裝過的Java物件。
下面是最終的測試程式碼,展示如何使用PriorityQueue:
PriorityQueueExample.java
1 |
package com.journaldev.collections; |
2 |
3 |
import java.util.Comparator; |
4 |
import java.util.PriorityQueue; |
5 |
import java.util.Queue; |
6 |
import java.util.Random; |
7 |
8 |
public class PriorityQueueExample
{ |
9 |
10 |
public static void main(String[]
args) { |
11 |
12 |
//優先佇列自然排序示例 |
13 |
Queue<Integer>
integerPriorityQueue = new PriorityQueue<>( 7 ); |
14 |
Random
rand = new Random(); |
15 |
for ( int i= 0 ;i< 7 ;i++){ |
16 |
integerPriorityQueue.add( new Integer(rand.nextInt( 100 ))); |
17 |
} |
18 |
for ( int i= 0 ;i< 7 ;i++){ |
19 |
Integer
in = integerPriorityQueue.poll(); |
20 |
System.out.println( "Processing
Integer:" +in); |
21 |
} |
22 |
23 |
//優先佇列使用示例 |
24 |
Queue<Customer>
customerPriorityQueue = new PriorityQueue<>( 7 ,
idComparator); |
25 |
addDataToQueue(customerPriorityQueue); |
26 |
27 |
pollDataFromQueue(customerPriorityQueue); |
28 |
29 |
} |
30 |
31 |
//匿名Comparator實現 |
32 |
public static Comparator<Customer>
idComparator = new Comparator<Customer>(){ |
33 |
34 |
@Override |
35 |
public int compare(Customer
c1, Customer c2) { |
36 |
return ( int )
(c1.getId() - c2.getId()); |
37 |
} |
38 |
}; |
39 |
40 |
//用於往佇列增加資料的通用方法 |
41 |
private static void addDataToQueue(Queue<Customer>
customerPriorityQueue) { |
42 |
Random
rand = new Random(); |
43 |
for ( int i= 0 ;
i< 7 ;
i++){ |
44 |
int id
= rand.nextInt( 100 ); |
45 |
customerPriorityQueue.add( new Customer(id, "Pankaj
" +id)); |
46 |
} |
47 |
} |
48 |
49 |
//用於從佇列取資料的通用方法 |
50 |
private static void pollDataFromQueue(Queue<Customer>
customerPriorityQueue) { |
51 |
while ( true ){ |
52 |
Customer
cust = customerPriorityQueue.poll(); |
53 |
if (cust
== null ) break ; |
54 |
System.out.println( "Processing
Customer with ID=" +cust.getId()); |
55 |
} |
56 |
} |
57 |
58 |
} |
注意我用實現了Comparator介面的Java匿名類,並且實現了基於id的比較器。
當我執行以上測試程式時,我得到以下輸出:
1 |
Processing
Integer:9 |
2 |
Processing
Integer:16 |
3 |
Processing
Integer:18 |
4 |
Processing
Integer:25 |
5 |
Processing
Integer:33 |
6 |
Processing
Integer:75 |
7 |
Processing
Integer:77 |
8 |
Processing
Customer with ID=6 |
9 |
Processing
Customer with ID=20 |
10 |
Processing
Customer with ID=24 |
11 |
Processing
Customer with ID=28 |
12 |
Processing
Customer with ID=29 |
13 |
Processing
Customer with ID=82 |
14 |
Processing
Customer with ID=96 |
從輸出結果可以清楚的看到,最小的元素在佇列的頭部因而最先被取出。如果不實現Comparator,在建立customerPriorityQueue時會丟擲ClassCastException。
1 |
Exception in thread "main" java.lang.ClassCastException:
com.journaldev.collections.Customer cannot be cast to java.lang.Comparable |
2 |
at
java.util.PriorityQueue.siftUpComparable(PriorityQueue.java:633) |
3 |
at
java.util.PriorityQueue.siftUp(PriorityQueue.java:629) |
4 |
at
java.util.PriorityQueue.offer(PriorityQueue.java:329) |
5 |
at
java.util.PriorityQueue.add(PriorityQueue.java:306) |
6 |
at
com.journaldev.collections.PriorityQueueExample.addDataToQueue(PriorityQueueExample.java:45) |
7 |
at
com.journaldev.collections.PriorityQueueExample.main(PriorityQueueExample.java:25) |
以上就是優先佇列的全部內容,如果你喜歡這篇文章,請參與分享或者評論。
原文連結: journaldev 翻譯:ImportNew.com - ImportNew讀者
譯文連結:http://www.importnew.com/6932.html
[ 轉載請保留原文出處、譯者、譯文連結和上面的微信二維碼圖片。]
相關文章
相關文章
- .NET 6 優先佇列 PriorityQueue 實現分析佇列
- MaxHeap 最大堆 MinHeap 最小堆 PriorityQueue 優先佇列實現佇列
- java使用PriorityQueue即優先佇列實現大根堆和小根堆Java佇列
- 原始碼解析C#中PriorityQueue(優先順序佇列)的實現原始碼C#佇列
- PHP優先佇列PHP佇列
- Java優先順序佇列DelayedWorkQueue原理分析Java佇列
- Java優先佇列PriorityQueue的各種開啟方式以及一些你不知道的細節Java佇列
- STL 優先佇列 用法佇列
- 淺談優先佇列佇列
- 堆與優先佇列佇列
- Android程式設計師會遇到的演算法(part 6 優先順序佇列PriorityQueue)Android程式設計師演算法佇列
- 優先佇列和堆排序佇列排序
- 01揹包優先佇列優化佇列優化
- 佇列 優先順序佇列 python 程式碼實現佇列Python
- 棧,佇列,優先順序佇列簡單介面使用佇列
- NO GAME NO LIFE(優先佇列/最小堆)GAM佇列
- 優先佇列的比較器佇列
- 封裝優先順序佇列封裝佇列
- 三、資料結構演算法-棧、佇列、優先佇列、雙端佇列資料結構演算法佇列
- STL優先佇列最小堆最大堆佇列
- leetcode621——優先佇列的思路LeetCode佇列
- 演算法面試(三) 優先佇列演算法面試佇列
- 二叉堆實現優先佇列佇列
- 手擼優先佇列——二叉堆佇列
- C++ STL 優先佇列 (priority_queue)C++佇列
- 堆、堆排序和優先佇列的那些事排序佇列
- 最詳細版圖解優先佇列(堆)圖解佇列
- 【堆】【優先佇列】[NOIP2004]合併果子佇列
- Facebook的分散式優先順序佇列FOQS分散式佇列
- 8.13(優先佇列貪心維護+打表找規律+對頂堆優先佇列+DFS減枝+貪心dp)佇列
- 【Dijkstra演算法】未優化版+優先佇列優化版演算法優化佇列
- codeforces round 974(div.3)E(優先佇列實現dijstra演算法,devc++的優先佇列用greater報錯)佇列JS演算法devC++
- CodeForces - 960B:Minimize the error(優先佇列+貪心)Error佇列
- Sunscreen POJ - 3614(防曬油) 貪心-優先佇列佇列
- [USACO 2009 Feb Gold] Fair Shuttle (貪心+優先佇列)GoAI佇列
- CSP之公共鑰匙盒(模擬、排序、優先佇列)排序佇列
- Python3 執行緒優先順序佇列( Queue)Python執行緒佇列
- java佇列Java佇列
- Python 列表推導及優先順序佇列的實現Python佇列