hashMap是什麼

咱們要想知道HashMap是什麼就先要了解Hash和Map是什麼java

1、Hash是什麼
① 哈希查找是一種數據結構中用於 查找 的算法,相比於其餘查找算法,他的時間複雜度更
低,因此在實際應用中大量採起了哈希表的方式,Hashmap就是java內置的哈希查找的方法
② 哈希函數的基本思想: 將記錄的存儲地址和關鍵字之間創建一個肯定的對應關係。這樣,當想查找某條記錄時,咱們根據記錄的關鍵字就能夠獲得它的存儲地址,進而快速判斷這條記錄是否存在,存儲在哪裏。
③負載因子:負載因子是哈希表在其容量自動增長以前能夠達到多滿的一種尺度,它衡量的是一個散列表的空間的使用程度,負載因子越大表示散列表的裝填程度越高,反之愈小。若是負載因子越大,對空間的利用更充分,然然後果是查找效率的下降;若是負載因子過小,那麼散列表的數據將過於稀疏,對空間形成嚴重浪費。hashmap默認負載因子爲0.75,通常狀況下咱們是無需修改的。
④ 哈希函數的缺陷+改進方式: 在哈希存儲中,不一樣的關鍵字可能映射到了相同的地址,這就叫產生衝突,咱們必須相處衝突處理的方法。固然,前輩們已經相處了各類各樣的方法,我在這裏先不作深究。
⑤ 通過上述討論,咱們發現,哈希查找的時間複雜度最小(沒有衝突)是O(1)算法

2、Map是什麼
首先Map是java中的一個接口。它是java中的一種重要的數據結構。
Map是從鍵(關鍵字)到值(記錄)的映射,鍵不容許重複,每一個鍵最多能映射一個值。
在java中,有不少類實現了Map接口,HashMap就是其中的一個數組

3、Hashmap是什麼
HashMap是一個實現了Map接口的基於哈希表的類 。
也就是說,HashMap既有map的鍵值對特色,也有哈希表的特色
簡單點說,利用HashMap類:
查找時,給出一個關鍵字key,咱們能夠根據hash算法計算出key-value的存儲位置而後取出value
存儲時,咱們根據哈希算法計算出該鍵值對應該存儲的位置,將其存進去。
也就是說,當沒有衝突時,HashMap存取的時間複雜度爲O(1)
這是HashMap類的部分代碼(部分數據域和構造函數)數據結構

public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable {
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 默認初始容量
static final int MAXIMUM_CAPACITY = 1 << 30;  //HashMap的最大容量
static final float DEFAULT_LOAD_FACTOR = 0.75f; //默認負載因子0.75
static final int TREEIFY_THRESHOLD = 8; //當某條鏈表中元素的個數大於8時//將轉變爲紅黑樹
transient Node<K,V>[] table;  // table數組,每個元素都是一個Node對象,接下來會介紹Node是什麼
transient Set<Map.Entry<K,V>> entrySet;
transient int size;  //記錄哈希表中的鍵值對個數
int threshold;      //閾值,即當table中元素個數大於這個值就要resize()
final float loadFactor;  //加載因子

HashMap有四種構造函數函數

①第一種 容許用戶本身決定初始容量和加載因子,但這個初始容量不必定是HashMap真正的初始容量,下文會對此進行解釋this

public HashMap(int initialCapacity, float loadFactor) {
    if (initialCapacity < 0)//初始容量不能夠小於0
        throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity);
    if (initialCapacity > MAXIMUM_CAPACITY)
        initialCapacity = MAXIMUM_CAPACITY;//不能夠大於最大容量
    if (loadFactor <= 0 ||Float.isNaN(loadFactor))//加載因子不能夠小於0
        throw new IllegalArgumentException("Illegal load factor: " +
                                                         loadFactor);
    this.loadFactor = loadFactor;
    this.threshold = tableSizeFor(initialCapacity);
}

在構造函數中,咱們能夠看到,閾值利用tableSizeFor進行了計算,而此時的閾值並非真正的閾值,是數組的容量,咱們也會發現其實在構造函數中並無給table分配內存,這是由於在插入鍵值對時,put函數會判斷table是否爲null,若是是那麼用resize()函數爲其分配空間並計算真正的閾值code

其餘三種構造函數對象

public HashMap(int initialCapacity) {
    this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public HashMap() {
    this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
public HashMap(Map<? extends K, ? extends V> m) {
    this.loadFactor = DEFAULT_LOAD_FACTOR;
    putMapEntries(m, false);
}

}
【小貼士】
1.AbstractMap抽象類是什麼?
AbstractMap抽象類實現了Map接口的大部分方法,讓HashMap繼承它減小了實現Map接口的工做量。那它爲何是抽象類呢,由於它有惟一的一個抽象方法
Public abstract Set<Entry<K,V>> entrySet();
固然在HashMap中有不少方法對AbstractMap的方法進行了覆蓋繼承

下一節:HashMap的數據結構接口

相關文章
相關標籤/搜索