集合HashMap原理刨解JDK1.8(5)

HashMap繼承AbstractMap抽象類Map接口和Cloneable接口。Map接口如下方法,JDK1.8實現了一些默認方法

 public interface Map<K,V>{//K和v是類型參數,分別表示鍵(Key)和值( Value)的類型
            
            V put(K key, V value);//保存鍵值對,如果原來有key,覆蓋,返回原來的值
            
            V get( Object key);//根據鍵獲取值,沒找到,返回nu11
            
            V remove( Object key);//根據鍵刪除鍵值對,返回key原來的值,如果不存在,返回nu11
            
            int size();//査看Map中鍵值對的個數
            
            boolean isempty();//是否爲空
            
            boolean containskey( Object key);//查看是否包含某個鍵
            
            boolean containsvalue( Object value);//查看是否包含某個值
            
            void puta11(Map<? extends K,? extends V>m);//保存m中的所有鍵值對到當前Map
            
            void clear();//清空Map中所有鍵值對
            
            Set<K> keyset();//獲取Map中鍵的集合
            
            Collection lection<V> values();//獲取Map中所有值的集合
            
            Set<Map. Entry<K,V>> entryset();//獲取Map中的所有鍵值對
            
                interface Entry.<K,V> {//嵌套接口,表示一條鍵值對
                    K getkey();//鍵值對的鍵
                    V getvalue ();//鍵值對的值
                    V setvalue (V value);
                     boolean equals (Object o);
                     int hashcode ();
                }
            
                boolean equals(Object o);
                int hashcode();
                boolean containsvalue(Object value);

使用Map鍵是唯一,鍵keySet()方法返回的是Set,根據鍵可以刪除鍵值對。
在這裏插入圖片描述
HashMap構造方法,還有其它二個構造方法
1.默認構造一個DEFAULT_LOAD_FACTOR負載因子0.75f方法
2.參數設置initialCapacity初始容量負載因子loadFactor的初始值

//1
 public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
    }
 //2
 public HashMap(int initialCapacity, float loadFactor){
 ..
	}

HashMap默認變量,其它方法變量主要是操作這些靜態變量

  		//默認是16的容量
  		static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
  		//最大容量不能超過 1073741824
        static final int MAXIMUM_CAPACITY = 1 << 30;
        //負載因子0.75
        static final float DEFAULT_LOAD_FACTOR = 0.75f;
        //變樹的閾值
        static final int TREEIFY_THRESHOLD = 8;
        //樹退化鏈表閾值
        static final int UNTREEIFY_THRESHOLD = 6;
        //最小樹容量,生成樹最小容量64,閾值8
        static final int MIN_TREEIFY_CAPACITY = 64;

hashMap最上面還有一個靜態內部類,像這些是要被調用纔會執行。不像靜態方法靜態變量一開始就加載到方法區

 //鏈表的節點
 static class Node<K,V> implements Map.Entry<K,V> { ..
 
 //紅黑樹的節點
 static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {..

1.table是一個Entry類型的數組
2.entrySet
3.size實際鍵值對的個數
4.modCount改變的次數,在遍歷如果有修改添加會報異常ConcurrentModificationException
在這裏插入圖片描述
5.threshold表示閾值,當size個數大於等於threshold閾值擴容,例如table長度是16.loadFactor是0.75f,計算是16x0.74=12得出閾值是12,負載因子可以通過構造方法修改
6.loadFactor 負載因子

 		transient HashMap.Node<K,V>[] table;
        transient Set<Map.Entry<K,V>> entrySet;
        transient int size;
        transient int modCount;
        int threshold;
        final float loadFactor;

HashMap JDK1.8是數組+鏈表+樹,add()添加一次默認分配16容量的數組。擴容16計算負載因子得出是12.擴容是容量得2倍。內部有數組table[],每個元素table[i]指向一個單向鏈表。用鍵算出hash值,取模拿到數組中得索引位置,然後操作數組指向得單向鏈表。
在鏈表上操作是比較hash值,相同用equals方法比較,equals首先默認比較對象(==)引用地址相等,
然後比較是否字符串String,一個個轉成char字符內容比較。
自定義對象要重寫hashCode值和equals。Object有hashCode,返回值是int類型,代表每個對象重寫都有hash值,如果像Stirng對象每個對象都有hash值。這個hash值在對象裏面用不到,集合map中能用到。
hashCode相等,則對象不一定相等。對象相等hash一定相等。存儲對象依賴hash值,根據hash值比較不依賴對象比較,可以提高效率吧
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章