#PriorityQueue(int initialCapacity, Comparator super E> comparator)
| #建立一個初始容量為 initialCapacity的優先權佇列<strong></strong>,根據 指定的比較器對其元素進行比較 注意: initialCapacity不能小於1,否則會拋IllegalArgumentException異常
| ## 2、PriorityQueue中對元素的比較
看完了構造方法,我們重新來思考一個問題
優先隊列是如何實現有序的呢?因為優先權佇列就是藉助小根堆來實現的
在實作小根堆的過程我們知道這其中一定發生了元素的比較,所以PriorityQueue中的元素必須要能夠比較大小,那麼PriorityQueue是如何進行元素的比較呢?
PriorityQueue採用了:
Comparble和Comparator兩種方式。
1. Comparble是預設的內部比較方式,如果使用者插入自訂類型物件時,該類別物件必須實作Comparble接口,並覆寫compareTo方法
2. 使用者也可以選擇使用比較器對象,如果使用者插入自訂類型物件時,必須提供一個比較器類,讓該類別實作Comparator介面並覆寫compare方法。
我們看到這裡程式報錯了,為什麼呢?因為我們插入的Child物件是無法比較的(即沒有實作Comparable介面又沒有採用自訂的比較器)
可以看到
# 即我們採用了預設的比較方法Comparable介面中的compareTo方法
#此時我們再次看一下報錯訊息
看來是在往PriorityQueue中插入元素的時候出現了問題
##那麼我們打開PriorityQueue的原始碼看一下(下面是PriorityQueue中offer方法的原始碼)
再看看shiftUp的原始碼
繼續點進去siftUpComparable
此時再回過頭來看看我們放到PriorityQueue中的Child對象,他即沒有自訂比較器又沒有實作Comparable接口,當然報錯呀!
那麼好吧我們在Child類別中實作Comparable接口,按年齡進行比較
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; // 默认实现小根堆
}
@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, "小强"));
System.out.println(priorityQueue);
}
}
如果要實作大根堆,也好辦
上面我們是實作了Compable接口,那麼如果我們自訂一個年齡比較器呢?
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; // 实现小根堆
// return o2.ae - o1.age 实现大根堆
}
}
public class TestPriorityQueue {
public static void main(String[] args) {
AgeComparator ageComparator = new AgeComparator();
// 创建具有默认初始容量的 PriorityQueue ,并根据指定的比较器对其元素进行排序。
PriorityQueue<Child> priorityQueue = new PriorityQueue<>(ageComparator);
// 可以看到这里我的Child对象虽然没有实现Comparable接口,但因为我们对Child对象自定义了一个年龄比较器,所以插入元素不会报错
priorityQueue.offer(new Child(12, "小亮"));
priorityQueue.offer(new Child(11, "小红"));
priorityQueue.offer(new Child(8, "小强"));
System.out.println(priorityQueue);
}
}
3、插入/刪除/取得優先順序最高的元素
##函數名
功能介紹 |
|
boolean offer(E e)
插入元素e,插入成功傳回true,如果e物件為空,拋出NullPointerException異常,時 | 間複雜度,注意:空間不夠時候會進行擴容
|
E peek()## 取得優先順序最高的元素,如果優先權佇列為空,則傳回null |
| E poll()
移除優先權最高的元素並返回,如果優先權佇列為空,傳回null |
| int size()
取得有效元素的數量 |
| void
clear()
清空
|
|
boolean
isEmty()
偵測優先權佇列是否為空,為空返回true
|
|
推薦學習:《java影片教學
》