【集合】HashMap 1.7

面試題:

  1. hashmap談一談
  2. hashmap的set和get的時間復(fù)雜度是多少?為什么是O(1), hashmap 在jdk1.8是線程安全的嗎?
    為什么是線程安全的?concureenthashmap了解嗎?他是如何實現(xiàn)線程安全的?
  3. HashMap
    查詢時間復(fù)雜度,有沖突呢
    HashCode 函數(shù)設(shè)計
    如何用HashMap 加鎖 保證線程安全,不可以用JUC下類
  4. HashMap 的插入時間復(fù)雜度
  5. Java中HashMap與HashTable區(qū)別
  6. Java中HashMap底層數(shù)據(jù)結(jié)構(gòu)
  7. hashmap底層結(jié)構(gòu),紅黑樹什么時候退化,如何擴容
  8. hashmap的默認(rèn)數(shù)組長度是多少,hashmap中的取余操作是怎么做的
  9. HashMap為什么是非線程安全的
  10. HashMap有了解嗎?HashMap的時間復(fù)雜度?HashMap中Hash沖突是怎么解決的?鏈表的上一級結(jié)構(gòu)是什么?Java8中的HashMap有什么變化?紅黑樹需要比較大小才能進行插入,是依據(jù)什么進行比較的?其他Hash沖突解決方式?
  11. hashmap如何解決hash沖突,為什么hashmap中的鏈表需要轉(zhuǎn)成紅黑樹?
  12. hashmap擴容時每個entry需要再計算一次hash嗎?
  13. hashmap的數(shù)組長度為什么要保證是2的冪?
  14. hashmap什么時候會觸發(fā)擴容?

0、1.7的實現(xiàn)由數(shù)組加上鏈表實現(xiàn)

1、Entry結(jié)構(gòu)

 Entry(int h, K k, V v, Entry<K,V> n) {
            value = v;
            next = n;
            key = k;
            hash = h;
        }
 /**
     * The table, resized as necessary. Length MUST Always be a power of two.
     */
table = new Entry[capacity];
table

2、public V put(K key, V value)操作

1、首先判斷table是否為空,如果空,就去創(chuàng)建size為capacity的Entry數(shù);
2、不為空,判斷key是否為null,如果為null,就putForNullKey(value);
3、如果不為null,就計算key的hash值,再根據(jù)hash值和 table.length計算對應(yīng)在數(shù)組中的下標(biāo);
4、根據(jù)下標(biāo)去看對應(yīng)的鏈上是否有key相同的節(jié)點,如果有就把該節(jié)點的值覆蓋掉,返回舊的值;
5、如果對應(yīng)下標(biāo)為null,或者找不到相同key的節(jié)點,就使用頭插法,將新的new Entry<>(hash, key, value, e),放在table[bucketIndex]上。
6、5中還涉及到table擴容的問題。

    public V put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            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;
    }

1、觸發(fā)擴容

如果size 的大小大于等于了capacity * loadFactor ,就會觸發(fā)擴容,容量變?yōu)樵瓉淼膬杀叮?/p>

threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
if ((size >= threshold) && (null != table[bucketIndex]))
2、hashmap擴容時每個entry需要再計算一次hash嗎?

不是,首先key為null的entry就不需要重新計算,其次rehash幾乎不會觸發(fā)

3、Hashmap的默認(rèn)數(shù)組長度是多少,hashmap中的取余操作是怎么做的

默認(rèn)16, 取余h & (length-1)

 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
 static int indexFor(int h, int length) {
        // assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2";
        return h & (length-1);
    }
4、HashMap為什么是非線程安全的
5、Java中HashMap與HashTable區(qū)別
6、Java中HashMap如何優(yōu)化

https://www.cnblogs.com/heyonggang/p/9112731.html

HashMap?ConcurrentHashMap?相信看完這篇沒人能難住你!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容