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

Java中的LinkedHashMap源碼詳解

 更新時間:2023年09月05日 10:43:31   作者:Fly_Fly_Zhang  
這篇文章主要介紹了Java中的LinkedHashMap源碼詳解,LinkedHashMap的實現(xiàn)方式是將所有的Entry節(jié)點鏈入一個雙向鏈表,并且它的底層數(shù)據(jù)結(jié)構(gòu)是HashMap,因此,LinkedHashMap具有HashMap的所有特性,但在存取元素的細節(jié)實現(xiàn)上有所不同,需要的朋友可以參考下

LinkedHashMap

特點:

底層數(shù)據(jù)結(jié)構(gòu):

  • 數(shù)組加鏈表用來存儲數(shù)據(jù);
  • header雙向鏈表用來實現(xiàn)數(shù)據(jù)插入有序或者訪問有序;

LinkedHashMap數(shù)據(jù)存儲圖

繼承關(guān)系:

public class LinkedHashMap<K,V>
    extends HashMap<K,V> //繼承了HashMap
    implements Map<K,V>//實現(xiàn)了Map接口
{
  •  默認數(shù)組大小:16 ==>繼承父類
  •  loadFactor(默認加載因子):0.75 ==>繼承父類

基本屬性:下面為LinkedHashMap特有,別的屬性全部繼承HashMap;

     private transient Entry<K,V> header; //頭結(jié)點
     private final boolean accessOrder;//順序性; true(訪問有序); false(插入有序)

header如何初始化:header初始化需要調(diào)用重寫后的 init()方法,創(chuàng)建一個不存儲數(shù)據(jù)的entry實體,而init方法是在父類的構(gòu)造函數(shù)中被調(diào)用,子類的初始化都會調(diào)用父類的構(gòu)造函數(shù),從而實現(xiàn)了header的初始化;

//子類重寫方法;
@Override
    void init() {
        header = new Entry<>(-1, null, null, null); //hash值為-1;
        header.before = header.after = header;
    }
   //父類構(gòu)造函數(shù):
    public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
        this.loadFactor = loadFactor;
        threshold = initialCapacity;
        init(); //在LinkedHashMap起作用,用來初始化header;
    }

構(gòu)造函數(shù):均是調(diào)用父類對應(yīng)的構(gòu)造函數(shù)

 public LinkedHashMap(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor);//調(diào)用父類的構(gòu)造函數(shù)
        accessOrder = false; 
    }
     //只指定數(shù)組大小
    public LinkedHashMap(int initialCapacity) {
        super(initialCapacity); 
        accessOrder = false;
    }
    public LinkedHashMap() {
        super();
        accessOrder = false;
    }
    public LinkedHashMap(Map<? extends K, ? extends V> m) {
        super(m);
        accessOrder = false;
    }
     //指定數(shù)組大小。加載因子,以及確定使用何種有序
    public LinkedHashMap(int initialCapacity,
                         float loadFactor,
                         boolean accessOrder) {
        super(initialCapacity, loadFactor);
        this.accessOrder = accessOrder;
    }

增長方式:繼承父類,2*table.length; CRUD(增刪改查): put: 調(diào)用的是父類的put方法,但是對put方法中一些相關(guān)函數(shù)進行重寫;

// (父類HashMap實現(xiàn))
public V put(K key, V value) {
    if (table == EMPTY_TABLE) {//如果table為空,創(chuàng)建默認數(shù)組
        inflateTable(threshold);
    }
    if (key == null)//對key進行特殊處理,key為null總在0號角標鏈表中
        return putForNullKey(value);
    int hash = hash(key);
    int i = indexFor(hash, table.length); //通過hash找到對應(yīng)角標
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
    //遍歷該角標倆表,找到對應(yīng)key值
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
        //找到key值將value值進行更新,并返回舊的value值
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);//此方法在子類LinkedHashMap重寫,發(fā)揮作用;
				//針對LinkedHashMap,確定是插入有序,還是插入有序;
				//如果是訪問有序,將原節(jié)點刪除,并添加到header最后
            return oldValue;
        }
    }
    modCount++;
    addEntry(hash, key, value, i);//現(xiàn)有集合中沒找到key,那么創(chuàng)建一個新的entry實體
    return null;
}
//(當前類LinkedHashMap實現(xiàn))
void addEntry(int hash, K key, V value, int bucketIndex) {
//目前此函數(shù)并沒有看出與父類的區(qū)別
    super.addEntry(hash, key, value, bucketIndex);//調(diào)用父類創(chuàng)建entry實體
    // Remove eldest entry if instructed
    Entry<K,V> eldest = header.after;
    if (removeEldestEntry(eldest)) {//總返回false;這句等于無效代碼,留作后用;
        removeEntryForKey(eldest.key);
    }
}
//(父類HashMap實現(xiàn))
void addEntry(int hash, K key, V value, int bucketIndex) {
    if ((size >= threshold) && (null != table[bucketIndex])) {
    //如果集合中元素個數(shù)已經(jīng)大于閾值,那么進行擴容;
        resize(2 * table.length);//二倍擴容
        hash = (null != key) ? hash(key) : 0; 
        bucketIndex = indexFor(hash, table.length); 找到新的key對應(yīng)的數(shù)組角標
    }
    createEntry(hash, key, value, bucketIndex);//創(chuàng)建entry實體,子類重寫
}
//(當前類LinkedHashMap實現(xiàn))
void createEntry(int hash, K key, V value, int bucketIndex) {
    HashMap.Entry<K,V> old = table[bucketIndex];
    Entry<K,V> e = new Entry<>(hash, key, value, old);//頭插法
    table[bucketIndex] = e;
    e.addBefore(header);//實現(xiàn)第二功能,使數(shù)據(jù)實現(xiàn)插入有序;
    size++;
}
//(當前類LinkedHashMap實現(xiàn)) ,addBefore為子類Entry內(nèi)部類中的方法,
//Entry多了兩個屬性,before(前驅(qū)),after(后驅(qū))
private void addBefore(Entry<K,V> existingEntry) {
//使header實現(xiàn)插入有序,header所處鏈表實質(zhì)上為一個循環(huán)的雙向鏈表;
//將header.after理解為頭結(jié)點的下一個結(jié)點,將header.before理解為尾結(jié)點;新結(jié)點插入位置為尾插
    after  = existingEntry;//新的尾結(jié)點鏈接頭結(jié)點
    before = existingEntry.before;//新的尾結(jié)點的前驅(qū)鏈接舊的尾結(jié)點
    before.after = this;//舊的尾結(jié)點的下一結(jié)點鏈接新的尾結(jié)點
    after.before = this;//新的尾結(jié)點的下一結(jié)點的前驅(qū)鏈接新的尾結(jié)點
    //當然這句代碼可以改為existingEntry.before=this;//頭結(jié)點的前驅(qū)鏈接新的尾結(jié)點
}
  //根據(jù)put操作和get操作,并且根據(jù)當前集合是插入有序還是訪問有序,進行操作; 
  void recordAccess(HashMap<K,V> m) { 
            LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
            if (lm.accessOrder) { //訪問有序,刪除原節(jié)點,并將新節(jié)點添加到最后;
                lm.modCount++;
                remove();//刪除當前節(jié)點
                addBefore(lm.header);//在末尾添加被刪除節(jié)點
            }
        }

HashMap與LinkedHashMap的不同的點:

LinkedHashMap可以保證插入有序或者訪問有序

 內(nèi)部類Entry多了before / after

 實現(xiàn)兩種數(shù)據(jù)結(jié)構(gòu),HashMap只實現(xiàn)數(shù)組+鏈表的數(shù)據(jù)結(jié)構(gòu),LinkedHashMap實現(xiàn)數(shù)組加鏈表和雙向鏈表環(huán)的數(shù)據(jù)結(jié)構(gòu)。

 LinkedHashMap繼承自HashMap。兩者數(shù)組加鏈表得數(shù)據(jù)結(jié)構(gòu),功能差不多。但是在rehash時,LinkedHashMap直接使用鏈表環(huán)進行hash。這樣可以保證鏈表環(huán)相對不變。

到此這篇關(guān)于Java中的LinkedHashMap源碼詳解的文章就介紹到這了,更多相關(guān)LinkedHashMap源碼詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java 遍歷Map及Map轉(zhuǎn)化為二維數(shù)組的實例

    java 遍歷Map及Map轉(zhuǎn)化為二維數(shù)組的實例

    這篇文章主要介紹了java 遍歷Map及Map轉(zhuǎn)化為二維數(shù)組的實例的相關(guān)資料,希望通過本文能幫助到大家,實現(xiàn)這樣的功能,需要的朋友可以參考下
    2017-08-08
  • Java Web用戶登錄實例代碼

    Java Web用戶登錄實例代碼

    這篇文章主要介紹了Java Web用戶登錄實例代碼的相關(guān)資料,非常不錯具有參考借鑒價值,感興趣的朋友一起看看吧
    2016-05-05
  • springboot?整合?dubbo?的實現(xiàn)組聚合詳情

    springboot?整合?dubbo?的實現(xiàn)組聚合詳情

    這篇文章主要介紹了springboot整合dubbo的實現(xiàn)組聚合詳情,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-07-07
  • mybatis中mapper.xml文件的常用屬性及標簽講解

    mybatis中mapper.xml文件的常用屬性及標簽講解

    這篇文章主要介紹了mybatis中mapper.xml文件的常用屬性及標簽講解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Mybatis-Plus實現(xiàn)用戶ID自增出現(xiàn)的問題解決

    Mybatis-Plus實現(xiàn)用戶ID自增出現(xiàn)的問題解決

    項目基于 SpringBoot + MybatisPlus 3.5.2 使用數(shù)據(jù)庫自增ID時, 出現(xiàn)重復(fù)鍵的問題,本文就來介紹一下解決方法,感興趣的可以了解一下
    2023-09-09
  • Java中父類強制轉(zhuǎn)換子類問題解決

    Java中父類強制轉(zhuǎn)換子類問題解決

    在Java編程中繼承是基礎(chǔ),但父類轉(zhuǎn)換為子類時需謹慎,正確的轉(zhuǎn)換要求父類引用實際指向子類對象,錯誤轉(zhuǎn)換可能引發(fā)ClassCastException,解決方案包括使用instanceof關(guān)鍵字檢查、利用泛型避免轉(zhuǎn)換、以及通過多態(tài)性避免直接轉(zhuǎn)換,感興趣的可以了解一下
    2024-11-11
  • 實例詳解Java中如何對方法進行調(diào)用

    實例詳解Java中如何對方法進行調(diào)用

    這篇文章主要介紹了實例詳解Java中如何對方法進行調(diào)用,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-10-10
  • 通過Java讀取xml文件內(nèi)容過程解析

    通過Java讀取xml文件內(nèi)容過程解析

    這篇文章主要介紹了通過Java讀取xml文件內(nèi)容過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • idea打開運行配置java?web項目的全過程

    idea打開運行配置java?web項目的全過程

    這篇文章主要給大家介紹了關(guān)于idea打開運行配置java?web項目的相關(guān)資料,有些時候我們用IDEA跑之前用eclipse中運行的項目的時候,總是不止所措,要不就是只展示html,要不就是不能部署成功,需要的朋友可以參考下
    2023-08-08
  • Java內(nèi)存區(qū)域和內(nèi)存模型講解

    Java內(nèi)存區(qū)域和內(nèi)存模型講解

    今天小編就為大家分享一篇關(guān)于Java內(nèi)存區(qū)域和內(nèi)存模型講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01

最新評論

吉安市| 禹州市| 麻城市| 农安县| 汨罗市| 观塘区| 宁强县| 临泉县| 绥宁县| 浦江县| 南京市| 青浦区| 大丰市| 扎鲁特旗| 安远县| 宁津县| 乐陵市| 淮南市| 孝义市| 德钦县| 化州市| 罗源县| 浮山县| 南江县| 合水县| 昂仁县| 都昌县| 离岛区| 长垣县| 凭祥市| 山阴县| 山东省| 雷山县| 泗洪县| 修文县| 托克逊县| 黔南| 即墨市| 新乡市| 郑州市| 巩义市|