久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

深入理解HashMap的擴(kuò)容機(jī)制

 liang1234_ 2018-05-18


一,、什么時(shí)候擴(kuò)容:

網(wǎng)上總結(jié)的會(huì)有很多,但大多都總結(jié)的不夠完整或者不夠準(zhǔn)確,。大多數(shù)可能值說(shuō)了滿足我下面條件一的情況,。

擴(kuò)容必須滿足兩個(gè)條件:

1、 存放新值的時(shí)候當(dāng)前已有元素的個(gè)數(shù)必須大于等于閾值

2,、 存放新值的時(shí)候當(dāng)前存放數(shù)據(jù)發(fā)生hash碰撞(當(dāng)前key計(jì)算的hash值換算出來(lái)的數(shù)組下標(biāo)位置已經(jīng)存在值)

 

二,、下面我們看源碼,如下:

首先是put()方法

public V put(K key, V value) {
    //判斷當(dāng)前Hashmap(底層是Entry數(shù)組)是否存值(是否為空數(shù)組)
    if (table == EMPTY_TABLE) {
      inflateTable(threshold);//如果為空,,則初始化
    }
    
    //判斷key是否為空
    if (key == null)
      return putForNullKey(value);//hashmap允許key為空
    
    //計(jì)算當(dāng)前key的哈希值    
    int hash = hash(key);
    //通過(guò)哈希值和當(dāng)前數(shù)據(jù)長(zhǎng)度,,算出當(dāng)前key值對(duì)應(yīng)在數(shù)組中的存放位置
    int i = indexFor(hash, table.length);
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
      Object k;
      //如果計(jì)算的哈希位置有值(及hash沖突),且key值一樣,,則覆蓋原值value,,并返回原值value
      if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
        V oldValue = e.value;
        e.value = value;
        e.recordAccess(this);
        return oldValue;
      }
    }
    modCount ;
    //存放值的具體方法
    addEntry(hash, key, value, i);
    return null;
  }

   

在put()方法中有調(diào)用addEntry()方法,這個(gè)方法里面是具體的存值,,在存值之前還有判斷是否需要擴(kuò)容

void addEntry(int hash, K key, V value, int bucketIndex) {
    //1,、判斷當(dāng)前個(gè)數(shù)是否大于等于閾值
    //2、當(dāng)前存放是否發(fā)生哈希碰撞
    //如果上面兩個(gè)條件否發(fā)生,,那么就擴(kuò)容
    if ((size >= threshold) && (null != table[bucketIndex])) {
      //擴(kuò)容,,并且把原來(lái)數(shù)組中的元素重新放到新數(shù)組中
      resize(2 * table.length);
      hash = (null != key) ? hash(key) : 0;
      bucketIndex = indexFor(hash, table.length);
    }
    createEntry(hash, key, value, bucketIndex);
  }

  

如果需要擴(kuò)容,調(diào)用擴(kuò)容的方法resize()

void resize(int newCapacity) {
    Entry[] oldTable = table;
    int oldCapacity = oldTable.length;
    //判斷是否有超出擴(kuò)容的最大值,,如果達(dá)到最大值則不進(jìn)行擴(kuò)容操作
    if (oldCapacity == MAXIMUM_CAPACITY) {
      threshold = Integer.MAX_VALUE;
      return;
    }
    Entry[] newTable = new Entry[newCapacity];
    // transfer()方法把原數(shù)組中的值放到新數(shù)組中
    transfer(newTable, initHashSeedAsNeeded(newCapacity));
    //設(shè)置hashmap擴(kuò)容后為新的數(shù)組引用
    table = newTable;
    //設(shè)置hashmap擴(kuò)容新的閾值
    threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY 1);
  }

 

transfer()在實(shí)際擴(kuò)容時(shí)候把原來(lái)數(shù)組中的元素放入新的數(shù)組中

void transfer(Entry[] newTable, boolean rehash) {
    int newCapacity = newTable.length;
    for (Entry<K,V> e : table) {
      while(null != e) {
        Entry<K,V> next = e.next;
        if (rehash) {
          e.hash = null == e.key ? 0 : hash(e.key);
        }
        //通過(guò)key值的hash值和新數(shù)組的大小算出在當(dāng)前數(shù)組中的存放位置
        int i = indexFor(e.hash, newCapacity);
        e.next = newTable[i];
        newTable[i] = e;
        e = next;
      }
    }
  }

  

三,、總結(jié):

Hashmap的擴(kuò)容需要滿足兩個(gè)條件:當(dāng)前數(shù)據(jù)存儲(chǔ)的數(shù)量(即size())大小必須大于等于閾值;當(dāng)前加入的數(shù)據(jù)是否發(fā)生了hash沖突,。

 

因?yàn)樯厦孢@兩個(gè)條件,,所以存在下面這些情況

(1)、就是hashmap在存值的時(shí)候(默認(rèn)大小為16,,負(fù)載因子0.75,,閾值12),可能達(dá)到最后存滿16個(gè)值的時(shí)候,,再存入第17個(gè)值才會(huì)發(fā)生擴(kuò)容現(xiàn)象,,因?yàn)榍?6個(gè)值,每個(gè)值在底層數(shù)組中分別占據(jù)一個(gè)位置,,并沒(méi)有發(fā)生hash碰撞,。

(2)、當(dāng)然也有可能存儲(chǔ)更多值(超多16個(gè)值,,最多可以存26個(gè)值)都還沒(méi)有擴(kuò)容,。原理:前11個(gè)值全部hash碰撞,存到數(shù)組的同一個(gè)位置(這時(shí)元素個(gè)數(shù)小于閾值12,,不會(huì)擴(kuò)容),,后面所有存入的15個(gè)值全部分散到數(shù)組剩下的15個(gè)位置(這時(shí)元素個(gè)數(shù)大于等于閾值,但是每次存入的元素并沒(méi)有發(fā)生hash碰撞,,所以不會(huì)擴(kuò)容),,前面11 15=26,所以在存入第27個(gè)值的時(shí)候才同時(shí)滿足上面兩個(gè)條件,,這時(shí)候才會(huì)發(fā)生擴(kuò)容現(xiàn)象,。

 


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多