Java PriorityQueue數(shù)據(jù)結(jié)構(gòu)接口原理及用法
PriorityQueue是從JDK1.5開始提供的新的數(shù)據(jù)結(jié)構(gòu)接口,它是一種基于優(yōu)先級(jí)堆的極大優(yōu)先級(jí)隊(duì)列。優(yōu)先級(jí)隊(duì)列是不同于先進(jìn)先出隊(duì)列的另一種隊(duì)列。每次從隊(duì)列中取出的是具有最高優(yōu)先權(quán)的元素。如果不提供Comparator的話,優(yōu)先隊(duì)列中元素默認(rèn)按自然順序排列,也就是數(shù)字默認(rèn)是小的在隊(duì)列頭,字符串則按字典序排列(參閱 Comparable),也可以根據(jù) Comparator 來指定,這取決于使用哪種構(gòu)造方法。優(yōu)先級(jí)隊(duì)列不允許 null 元素。依靠自然排序的優(yōu)先級(jí)隊(duì)列還不允許插入不可比較的對(duì)象(這樣做可能導(dǎo)致 ClassCastException)
優(yōu)先級(jí)隊(duì)列是無界的,但是有一個(gè)內(nèi)部容量,控制著用于存儲(chǔ)隊(duì)列元素的數(shù)組大小。它通常至少等于隊(duì)列的大小。隨著不斷向優(yōu)先級(jí)隊(duì)列添加元素,其容量會(huì)自動(dòng)增加。無需指定容量增加策略的細(xì)節(jié)
簡單應(yīng)用:
package test;
import java.util.PriorityQueue;
public class PriorityQueueTest1 {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
PriorityQueue queue = new PriorityQueue();
queue.add("AAAAA"); // Add接受的參數(shù)是Obj,PriorityQueue使用integer String等基本的數(shù)據(jù)類型時(shí),默認(rèn)new時(shí)有參數(shù),如果不寫則是按照默認(rèn)排序
queue.add("BBBBB");
queue.add("CCCCC");
queue.add("DDDDD");
System.out.println(queue.peek()); // 獲取但不移除此隊(duì)列的頭
System.out.println(queue.poll()); // 獲取并移除此隊(duì)列的頭
System.out.println(queue.poll());
queue.offer("ZZZZZ"); // 將指定的元素插入此優(yōu)先級(jí)隊(duì)列
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue.poll()); // 到這里已經(jīng)沒有元素,打印Null
}
}
定義比較器:
package test;
import java.util.Comparator;
import java.util.PriorityQueue;
@SuppressWarnings("unchecked")
public class PriorityQueueTest2 {
private static PriorityQueue queue = new PriorityQueue(10,new Comparators());
public static void main(String[] args) {
QueueObject queueObject = new QueueObject();
queueObject.setId(4);
queueObject.setObject("AAAAA");
queue.add(queueObject);
QueueObject queueObject1 = new QueueObject();
queueObject1.setId(1);
queueObject1.setObject("BBBBB");
queue.add(queueObject1);
QueueObject queueObject2 = new QueueObject();
queueObject2.setId(3);
queueObject2.setObject("CCCCC");
queue.add(queueObject2);
System.out.println(((QueueObject)queue.poll()).getObject());
System.out.println(((QueueObject)queue.poll()).getObject());
System.out.println(((QueueObject)queue.poll()).getObject());
}
}
class QueueObject {
private int id;
private Object object;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
}
@SuppressWarnings("unchecked")
class Comparators implements Comparator{
public int compare(Object arg0, Object arg1) {
int val1 = ((QueueObject)arg0).getId();
int val2 = ((QueueObject)arg1).getId();
return val1 < val2 ? 0 : 1;
}
}
注意事項(xiàng):
注意1:該隊(duì)列是用數(shù)組實(shí)現(xiàn),但是數(shù)組大小可以動(dòng)態(tài)增加,容量無限。
注意2:此實(shí)現(xiàn)不是同步的。不是線程安全的。如果多個(gè)線程中的任意線程從結(jié)構(gòu)上修改了列表, 則這些線程不應(yīng)同時(shí)訪問 PriorityQueue 實(shí)例,這時(shí)請(qǐng)使用線程安全的PriorityBlockingQueue 類。
注意3:不允許使用 null 元素。
注意4:此實(shí)現(xiàn)為插入方法(offer、poll、remove() 和 add 方法)提供 O(log(n)) 時(shí)間;
為 remove(Object) 和 contains(Object) 方法提供線性時(shí)間;
為檢索方法(peek、element 和 size)提供固定時(shí)間。
注意5:方法iterator()中提供的迭代器并不保證以有序的方式遍歷優(yōu)先級(jí)隊(duì)列中的元素。
至于原因可參考下面關(guān)于PriorityQueue的內(nèi)部實(shí)現(xiàn)
如果需要按順序遍歷,請(qǐng)考慮使用 Arrays.sort(pq.toArray())。
注意6:可以在構(gòu)造函數(shù)中指定如何排序。如:
- PriorityQueue()
- 使用默認(rèn)的初始容量(11)創(chuàng)建一個(gè) PriorityQueue,并根據(jù)其自然順序來排序其元素(使用 Comparable)。
- PriorityQueue(int initialCapacity)
- 使用指定的初始容量創(chuàng)建一個(gè) PriorityQueue,并根據(jù)其自然順序來排序其元素(使用 Comparable)。
- PriorityQueue(int initialCapacity, Comparator comparator)
- 使用指定的初始容量創(chuàng)建一個(gè) PriorityQueue,并根據(jù)指定的比較器comparator來排序其元素。
注意7:此類及其迭代器實(shí)現(xiàn)了 Collection 和 Iterator 接口的所有可選 方法。
PriorityQueue的內(nèi)部實(shí)現(xiàn)
PriorityQueue對(duì)元素采用的是堆排序,頭是按指定排序方式的最小元素。堆排序只能保證根是最大(最?。?,整個(gè)堆并不是有序的。
方法iterator()中提供的迭代器可能只是對(duì)整個(gè)數(shù)組的依次遍歷。也就只能保證數(shù)組的第一個(gè)元素是最小的
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Java?如何通過注解實(shí)現(xiàn)接口輸出時(shí)數(shù)據(jù)脫敏
- Java實(shí)現(xiàn)調(diào)用對(duì)方http接口得到返回?cái)?shù)據(jù)
- java開發(fā)之基于Validator接口的SpringMVC數(shù)據(jù)校驗(yàn)方式
- Java 利用DeferredResult實(shí)現(xiàn)http輪詢實(shí)時(shí)返回?cái)?shù)據(jù)接口
- 五分鐘帶你了解Java的接口數(shù)據(jù)校驗(yàn)
- java讀取其他服務(wù)接口返回的json數(shù)據(jù)示例代碼
- 淺析Java 數(shù)據(jù)結(jié)構(gòu)常用接口與類
- 如何使用java制作假數(shù)據(jù)接口
相關(guān)文章
深入理解Java動(dòng)態(tài)代理與靜態(tài)代理
這篇文章主要介紹了深入理解Java動(dòng)態(tài)代理與靜態(tài)代理,靜態(tài)代理,代理類和被代理的類實(shí)現(xiàn)了同樣的接口,代理類同時(shí)持有被代理類的引用,動(dòng)態(tài)代理的根據(jù)實(shí)現(xiàn)方式的不同可以分為JDK動(dòng)態(tài)代理和CGlib動(dòng)態(tài)代理2022-06-06
Java類型轉(zhuǎn)換valueOf與parseInt區(qū)別探討解析
這篇文章主要為大家介紹了Java類型轉(zhuǎn)換valueOf與parseInt區(qū)別探討解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
線程池調(diào)用kafka發(fā)送消息產(chǎn)生的內(nèi)存泄漏問題排查解決
這篇文章主要為大家介紹了線程池調(diào)用kafka發(fā)送消息產(chǎn)生的內(nèi)存泄漏問題排查解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
springboot的yml配置文件通過db2的方式整合mysql的教程
這篇文章主要介紹了springboot的yml配置文件通過db2的方式整合mysql的教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
java根據(jù)List內(nèi)對(duì)象的屬性排序方法
下面小編就為大家分享一篇java根據(jù)List內(nèi)對(duì)象的屬性排序方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-01-01
關(guān)于如何搭建CAS服務(wù)并將CAS項(xiàng)目導(dǎo)入IDEA
這篇文章主要介紹了關(guān)于如何搭建CAS服務(wù)并將CAS項(xiàng)目導(dǎo)入IDEA的問題,文中提供了詳細(xì)的圖文講解,需要的朋友可以參考下,如果有錯(cuò)誤的地方還請(qǐng)指正2023-03-03
Java數(shù)據(jù)結(jié)構(gòu)之圖的基礎(chǔ)概念和數(shù)據(jù)模型詳解
在現(xiàn)實(shí)生活中,有許多應(yīng)用場景會(huì)包含很多點(diǎn)以及點(diǎn)點(diǎn)之間的連接,而這些應(yīng)用場景我們都可以用即將要學(xué)習(xí)的圖這種數(shù)據(jù)結(jié)構(gòu)去解決。本文主要介紹了圖的基礎(chǔ)概念和數(shù)據(jù)模型,感興趣的可以了解一下2022-11-11

