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值比較不依賴對象比較,可以提高效率吧