最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java PriorityQueue優(yōu)先級隊列的使用方式

 更新時間:2026年02月02日 15:51:16   作者:吞吞吐吐大魔王  
PriorityQueue是一個優(yōu)先級隊列,可以按照優(yōu)先級處理對象,它繼承了Queue接口,底層是一個堆,可以實現(xiàn)大根堆或小根堆,常用方法包括offer、poll、peek、size等,插入元素時需要注意元素不能為null并且必須能夠進(jìn)行比較,大根堆可以通過傳入自定義的比較器實現(xiàn)

1. 場景引入

我們知道,Queue是一個先進(jìn)先出(FIFO)的隊列。

在很多應(yīng)用中,我們通常需要按照優(yōu)先情況對待處理對象進(jìn)行處理,比如首先處理優(yōu)先級最高的對象,然后處理次高的對象。最簡單的一個例子就是,在手機(jī)上玩游戲時,如果有來電,那么系統(tǒng)應(yīng)該優(yōu)先處理進(jìn)來的電話。

這個時候,我們發(fā)現(xiàn),要實現(xiàn)上述的操作,用Queue就不行了,因為Queue會嚴(yán)格按 FIFO 的原則取出隊首元素。故有了我們需要的優(yōu)先隊列:PriorityQueue

2. PriorityQueue 介紹

Java 中 PriorityQueue 繼承了 Queue 接口,它的底層是一個堆。

3. 知識點

PriorityQueue 的底層是一個數(shù)組

我們可以轉(zhuǎn)到它的定義,可以看到它的底層定義是一個數(shù)組。為了知道這個數(shù)組的初始大小有多大

再通過它的參構(gòu)造方法轉(zhuǎn)到定義,又可以看到

再點擊 this,轉(zhuǎn)到其定義,我們發(fā)現(xiàn)又跳到了一個含兩個參數(shù)的構(gòu)造方法

又在 PriorityQueue 的定義中 DEFAULT_INITIAL_CAPACITY = 11,即 initialCapacity = 11,所以我們可以知道數(shù)組的初始大小為11

PriorityQueue 的底層默認(rèn)是一個小根堆

如何使 PriorityQueue 的底層是一個大根堆?

引用上圖 PriorityQueue 的含參定義,我們知道第一個參數(shù)代表數(shù)組的大小,而第二個參數(shù)就一個比較器,傳給他的就是比較的方法,通過給他傳入大根堆的比較方式,我們就可以使 PriorityQueue 的底層變成大根堆

4. 常用方法

方法描述
boolean offer(E e)入隊列
E poll()出隊列
E peek()得到隊首元素
int size()返回集合中的元素個數(shù)

注意: 下面的示例都是一份代碼分開拿出來的,上下其實是有邏輯關(guān)系的

  • 示例一: 用 Priority Queue 創(chuàng)建一個優(yōu)先級隊列
PriorityQueue<Integer> queue=new PriorityQueue<>();
  • 示例二: 入隊列
queue.offer(10);
queue.offer(2);
queue.offer(5);
  • 示例三: 得到隊首元素
System.out.println(queue.peek());
// 結(jié)果為:2
  • 示例四: 出隊列
System.out.println(queue.poll());
// 結(jié)果為:2
  • 示例五: 返回集合中元素個數(shù)
System.out.println(queue.size());
// 結(jié)果為:2

5. 優(yōu)先級隊列插入元素的細(xì)節(jié)問題

當(dāng)我們使用優(yōu)先級隊列的時候,插入元素其實有個前提:

插入的元素不能是 null 或者元素之間必須能夠進(jìn)行比較

而基本的包裝類類型都可以進(jìn)行比較,如:Integer、Double、Float。但是對于我們自定義的類型,其實就可能不能比較,就如下面這個類當(dāng)我們使用優(yōu)先級隊列對它的對象進(jìn)行插入時,其實會報錯

class Student{
    private String name;
    private int age;

    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
    }
}
public class TestDemo{
    public static void main(String[] args){
        PriorityQueue<Student> queue=new PriorityQueue<>();
        queue.offer(new Student("Tom",18));
        queue.offer(new Student("Hen",34));
    }
}

這是因為優(yōu)先級隊列的底層默認(rèn)是一個小根堆,它存入元素時是需要進(jìn)行比較對象的大小的。

我們可以轉(zhuǎn)到 PriorityQueue 的無參構(gòu)造方法的定義看看

此時我們的 comparator 默認(rèn)是 null,我們再轉(zhuǎn)到 offer 方法的定義看看

好像并沒有什么異常,但是由于我 插入第二個元素時,i 不為0,所以要進(jìn)行 siftUp 方法,我們轉(zhuǎn)到它的定義

由于我們知道 comparator 為 null,那么則要進(jìn)行 siftUpComparable 方法,繼續(xù)轉(zhuǎn)到它的定義

我們發(fā)現(xiàn),創(chuàng)建的 Student 的對象,被強(qiáng)轉(zhuǎn)為了 Comparable<? super E>,并且還調(diào)用了 compareTo 方法。

如果大家有看過我寫的 解析 Java 的多態(tài)、抽象類和接口Java 對象的比較 這兩篇文章,那我就有講到 compareTo 這個方法。這個方法是 Comparable 的一個抽象方法,定義的是比較對象大小的一個規(guī)則。

因此為了解決這個問題,我們就可以使用和 Comparable 或 Comparator 接口相關(guān)的知識

6. PriorityQueue 大根堆的創(chuàng)建方式

6.1 思路

這里便不對源碼做具體分析,我們?nèi)绻?PriorityQueue 創(chuàng)建出的是一個大根堆,只需要對具體類型寫一個比較器即可

6.2 代碼實現(xiàn)

// 定義的某個要比較類型的比較器
class IntegerComparator implements Comparator<Integer>{
    @Override
    public int compare(Integer o1,Integer o2){
        // 如果第二個元素-第一個元素就是大根堆的實現(xiàn)方式,反之則為小根堆的創(chuàng)建方式,可以從源碼去了解
        return o2-o1;
    }
}
public class TestDemo{
    public static void main(String[] args){
        PriorityQueue<Integer> maxHeap=new PriorityQueue<>(IntegerComparator);
    }
}

6.3 使用匿名內(nèi)部類

上述代碼也可以寫成

public class TestDemo{
    public static void main(String[] args){
        PriorityQueue<Integer> maxHeap=new PriorityQueue<>(new Comparator<Integer>(){
            @Override
            public int compare(Integer o1,Integer o2){
                return o2-o1;
            }
        })
    }
}

這相當(dāng)使用了一個匿名的內(nèi)部類的方式去創(chuàng)建大根堆

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • play for scala 實現(xiàn)SessionFilter 過濾未登錄用戶跳轉(zhuǎn)到登錄頁面

    play for scala 實現(xiàn)SessionFilter 過濾未登錄用戶跳轉(zhuǎn)到登錄頁面

    這篇文章主要介紹了play for scala 實現(xiàn)SessionFilter 過濾未登錄用戶跳轉(zhuǎn)到登錄頁面的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • 一文搞懂Spring中的注解與反射

    一文搞懂Spring中的注解與反射

    這篇文章主要為大家介紹了Spring中的注解與反射的原理與實現(xiàn),文中的示例代碼講解詳細(xì),對我們了解Spring有一定的幫助,需要的可以參考一下
    2022-06-06
  • Java 輸入流中的read(byte[] b)方法詳解

    Java 輸入流中的read(byte[] b)方法詳解

    這篇文章主要介紹了Java 輸入流中的read(byte[] b)方法詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • Java的無參構(gòu)造函數(shù)用法實例分析

    Java的無參構(gòu)造函數(shù)用法實例分析

    這篇文章主要介紹了Java的無參構(gòu)造函數(shù)用法,結(jié)合實例形式分析了java無參構(gòu)造函數(shù)基本原理、用法及相關(guān)操作注意事項,需要的朋友可以參考下
    2019-09-09
  • springsecurity中http.permitall與web.ignoring的區(qū)別說明

    springsecurity中http.permitall與web.ignoring的區(qū)別說明

    這篇文章主要介紹了springsecurity中http.permitall與web.ignoring的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java實現(xiàn)堆算法的使用示例

    Java實現(xiàn)堆算法的使用示例

    本文主要介紹了Java實現(xiàn)堆算法的使用示例,Java中提供了一個Heap類,可以用來實現(xiàn)堆的操作,可以實現(xiàn)如插入、刪除、獲取最大最小值等,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • Springboot配置security basic path無效解決方案

    Springboot配置security basic path無效解決方案

    這篇文章主要介紹了Springboot配置security basic path無效解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • springboot 事件監(jiān)聽的實現(xiàn)方法

    springboot 事件監(jiān)聽的實現(xiàn)方法

    這篇文章主要介紹了springboot 事件監(jiān)聽的實現(xiàn)方法,并詳細(xì)的介紹了四種監(jiān)聽方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-04-04
  • java多線程實現(xiàn)取款小程序

    java多線程實現(xiàn)取款小程序

    這篇文章主要為大家詳細(xì)介紹了java多線程實現(xiàn)取款小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • java實現(xiàn)酒店管理系統(tǒng)

    java實現(xiàn)酒店管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)酒店管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-02-02

最新評論

横山县| 巴东县| 临泉县| 金湖县| 平塘县| 临洮县| 桐柏县| 密云县| 赤城县| 莫力| 新和县| 泗阳县| 蛟河市| 昌乐县| 抚宁县| 岐山县| 丰台区| 邻水| 济宁市| 蚌埠市| 济宁市| 韶关市| 卓资县| 汽车| 龙州县| 延吉市| 巴中市| 澄迈县| 武山县| 昔阳县| 太仓市| 祁连县| 承德县| 古蔺县| 湘西| 曲沃县| 北川| 石嘴山市| 大化| 沅江市| 东光县|