這篇文章主要講解了“Java集合框架之PriorityQueue優(yōu)先級(jí)隊(duì)列實(shí)例分析”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Java集合框架之PriorityQueue優(yōu)先級(jí)隊(duì)列實(shí)例分析”吧!
創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供安達(dá)網(wǎng)站建設(shè)、安達(dá)做網(wǎng)站、安達(dá)網(wǎng)站設(shè)計(jì)、安達(dá)網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、安達(dá)企業(yè)網(wǎng)站模板建站服務(wù),十年安達(dá)做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
Java集合框架中提供了PriorityQueue和PriorityBlockingQueue兩種類型的優(yōu)先級(jí)隊(duì)列,PriorityQueue是線程不安全的,PriorityBlockingQueue是線程安全的,本文主要介紹PriorityQueue
priorityQueue在Java集合框架中的關(guān)系如下:
1. 使用時(shí)必須導(dǎo)入PriorityQueue所在的包,即:
import java.util.PriorityQueue
2. PriorityQueue中放置的元素必須要能夠比較大小,不能插入無法比較大小的對(duì)象,否則會(huì)拋出
ClassCastException異常
3. 不能插入null對(duì)象,否則會(huì)拋出NullPointerException
4. 沒有容量限制,可以插入任意多個(gè)元素,其內(nèi)部可以自動(dòng)擴(kuò)容
5. 插入和刪除元素的時(shí)間復(fù)雜度為log以2為底的n
6. PriorityQueue底層使用了堆數(shù)據(jù)結(jié)構(gòu)
7. PriorityQueue默認(rèn)情況下是小堆---即每次獲取到的元素都是最小的元素(想要變成大堆,需要我們重新比較方法、默認(rèn)的比較方法是Comparable接口中的compareTo方法)
此處只是列出了PriorityQueue中常見的幾種構(gòu)造方式,其他的大家可以參考幫助文檔。
構(gòu)造器 | 功能介紹 |
PriorityQueue() | 創(chuàng)建一個(gè)空的優(yōu)先級(jí)隊(duì)列,默認(rèn)容量是11 |
PriorityQueue(int initialCapacity) | 創(chuàng)建一個(gè)初始容量為initialCapacity的優(yōu)先級(jí)隊(duì)列,注意:initialCapacity不能小于1,否則會(huì)拋IllegalArgumentException異常 |
PriorityQueue(Collection<? extends E> c) | 用一個(gè)集合來創(chuàng)建優(yōu)先級(jí)隊(duì)列 |
PriorityQueue(Comparator<? super E> comparator) | 創(chuàng)建具有默認(rèn)初始容量的優(yōu)先級(jí)隊(duì)列,并根據(jù)指定的比較器對(duì)其元素進(jìn)行比較 |
PriorityQueue(int initialCapacity, Comparator <? super E> comparator) | 創(chuàng)建一個(gè)初始容量為 注意:initialCapacity不能小于1,否則會(huì)拋IllegalArgumentException異常 |
看完了構(gòu)造方法,我們重新來思考一個(gè)問題
優(yōu)先級(jí)隊(duì)列是如何實(shí)現(xiàn)有序的呢?因?yàn)閮?yōu)先級(jí)隊(duì)列就是借助小根堆來實(shí)現(xiàn)的
在實(shí)現(xiàn)小根堆的過程我們知道這其中一定發(fā)生了元素的比較,所以PriorityQueue中的元素必須要能夠比較大小,那么PriorityQueue是如何進(jìn)行元素的比較呢?
PriorityQueue采用了:
Comparble和Comparator兩種方式。1. Comparble是默認(rèn)的內(nèi)部比較方式,如果用戶插入自定義類型對(duì)象時(shí),該類對(duì)象必須要實(shí)現(xiàn)Comparble接口,并覆寫compareTo方法
2. 用戶也可以選擇使用比較器對(duì)象,如果用戶插入自定義類型對(duì)象時(shí),必須要提供一個(gè)比較器類,讓該類實(shí)現(xiàn)Comparator接口并覆寫compare方法。
我們看到這里程序報(bào)錯(cuò)了,為什么呢?因?yàn)槲覀儾迦氲腃hild對(duì)象是不可比較的(即沒有實(shí)現(xiàn)Comparable接口又沒有采用自定義的比較器)
可以看到
即我們采用了默認(rèn)的比較方法Comparable接口中的compareTo方法
此時(shí)我們?cè)俅慰匆幌聢?bào)錯(cuò)信息
看來是在往PriorityQueue中插入元素的時(shí)候出現(xiàn)了問題
那么我們打開PriorityQueue的源碼看一下(下面是PriorityQueue中offer方法的源碼)
再看看shiftUp的源碼
繼續(xù)點(diǎn)進(jìn)去siftUpComparable
此時(shí)再回過頭來看看我們放到PriorityQueue中的Child對(duì)象,他即沒有自定義比較器又沒有實(shí)現(xiàn)Comparable接口,當(dāng)然報(bào)錯(cuò)呀!
那么好吧我們?cè)贑hild類中實(shí)現(xiàn)Comparable接口,按年齡進(jìn)行比較
import java.util.PriorityQueue; class Child implements Comparable<Child>{ int age; String name; public Child(int age, String name) { this.age = age; this.name = name; } @Override public int compareTo(Child o) { return this.age - o.age; // 默認(rèn)實(shí)現(xiàn)小根堆 } @Override public String toString() { return "Child{" + "age=" + age + ", name='" + name + '\'' + '}'; } } public class TestPriorityQueue { public static void main(String[] args) { PriorityQueue<Child> priorityQueue = new PriorityQueue<>(); priorityQueue.offer(new Child(12, "小亮")); priorityQueue.offer(new Child(11, "小紅")); priorityQueue.offer(new Child(8, "小強(qiáng)")); System.out.println(priorityQueue); } }
如果要實(shí)現(xiàn)大根堆,也好辦
上面我們是實(shí)現(xiàn)了Compable接口,那么如果我們自定義一個(gè)年齡比較器呢?
class Child { int age; String name; public Child(int age, String name) { this.age = age; this.name = name; } @Override public String toString() { return "Child{" + "age=" + age + ", name='" + name + '\'' + '}'; } } class AgeComparator implements Comparator<Child> { @Override public int compare(Child o1, Child o2) { return o1.age - o2.age; // 實(shí)現(xiàn)小根堆 // return o2.ae - o1.age 實(shí)現(xiàn)大根堆 } } public class TestPriorityQueue { public static void main(String[] args) { AgeComparator ageComparator = new AgeComparator(); // 創(chuàng)建具有默認(rèn)初始容量的 PriorityQueue ,并根據(jù)指定的比較器對(duì)其元素進(jìn)行排序。 PriorityQueue<Child> priorityQueue = new PriorityQueue<>(ageComparator); // 可以看到這里我的Child對(duì)象雖然沒有實(shí)現(xiàn)Comparable接口,但因?yàn)槲覀儗?duì)Child對(duì)象自定義了一個(gè)年齡比較器,所以插入元素不會(huì)報(bào)錯(cuò) priorityQueue.offer(new Child(12, "小亮")); priorityQueue.offer(new Child(11, "小紅")); priorityQueue.offer(new Child(8, "小強(qiáng)")); System.out.println(priorityQueue); } }
函數(shù)名 | 功能介紹 |
boolean offer(E e) | 插入元素e,插入成功返回true,如果e對(duì)象為空,拋出NullPointerException異常,時(shí) 間復(fù)雜度 ,注意:空間不夠時(shí)候會(huì)進(jìn)行擴(kuò)容 |
E peek() | 獲取優(yōu)先級(jí)最高的元素,如果優(yōu)先級(jí)隊(duì)列為空,返回null |
E poll() | 移除優(yōu)先級(jí)最高的元素并返回,如果優(yōu)先級(jí)隊(duì)列為空,返回null |
int size() | 獲取有效元素的個(gè)數(shù) |
void clear() | 清空 |
boolean isEmty() | 檢測(cè)優(yōu)先級(jí)隊(duì)列是否為空,為空返回true |
感謝各位的閱讀,以上就是“Java集合框架之PriorityQueue優(yōu)先級(jí)隊(duì)列實(shí)例分析”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)Java集合框架之PriorityQueue優(yōu)先級(jí)隊(duì)列實(shí)例分析這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
本文名稱:Java集合框架之PriorityQueue優(yōu)先級(jí)隊(duì)列實(shí)例分析
文章轉(zhuǎn)載:http://www.rwnh.cn/article30/jispso.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、全網(wǎng)營(yíng)銷推廣、網(wǎng)站排名、品牌網(wǎng)站設(shè)計(jì)、微信公眾號(hào)、網(wǎng)站導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)