摘要:經過上述討論,我們發現,哈希查找的時間復雜度最小沒有沖突是二是什么首先是中的一個接口。在中,有很多類實現了接口,就是其中的一個三是什么是一個實現了接口的基于哈希表的類。
我們要想知道HashMap是什么就先要了解Hash和Map是什么
一、Hash是什么
① 哈希查找是一種數據結構中用于 查找 的算法,相比于其他查找算法,他的時間復雜度更
低,所以在實際應用中大量采取了哈希表的方式,Hashmap就是java內置的哈希查找的方法
② 哈希函數的基本思想: 將記錄的存儲地址和關鍵字之間建立一個確定的對應關系。這樣,當想查找某條記錄時,我們根據記錄的關鍵字就可以得到它的存儲地址,進而快速判斷這條記錄是否存在,存儲在哪里。
③負載因子:負載因子是哈希表在其容量自動增加之前可以達到多滿的一種尺度,它衡量的是一個散列表的空間的使用程度,負載因子越大表示散列表的裝填程度越高,反之愈小。如果負載因子越大,對空間的利用更充分,然而后果是查找效率的降低;如果負載因子太小,那么散列表的數據將過于稀疏,對空間造成嚴重浪費。hashmap默認負載因子為0.75,一般情況下我們是無需修改的。
④ 哈希函數的缺陷+改進方式: 在哈希存儲中,不同的關鍵字可能映射到了相同的地址,這就叫產生沖突,我們必須相處沖突處理的方法。當然,前輩們已經相處了各種各樣的方法,我在這里先不做深究。
⑤ 經過上述討論,我們發現,哈希查找的時間復雜度最小(沒有沖突)是O(1)
二、Map是什么
首先Map是java中的一個接口。它是java中的一種重要的數據結構。
Map是從鍵(關鍵字)到值(記錄)的映射,鍵不允許重復,每個鍵最多能映射一個值。
在java中,有很多類實現了Map接口,HashMap就是其中的一個
三、Hashmap是什么
HashMap是一個實現了Map接口的基于哈希表的類 。
也就是說,HashMap既有map的鍵值對特點,也有哈希表的特點
簡單點說,利用HashMap類:
查找時,給出一個關鍵字key,我們可以根據hash算法計算出key-value的存儲位置然后取出value
存儲時,我們根據哈希算法計算出該鍵值對應該存儲的位置,將其存進去。
也就是說,當沒有沖突時,HashMap存取的時間復雜度為O(1)
這是HashMap類的部分代碼(部分數據域和構造函數)
public class HashMapextends AbstractMap implements Map , 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 [] table; // table數組,每一個元素都是一個Node對象,接下來會介紹Node是什么 transient Set > entrySet; transient int size; //記錄哈希表中的鍵值對個數 int threshold; //閾值,即當table中元素個數大于這個值就要resize() final float loadFactor; //加載因子
HashMap有四種構造函數
①第一種 允許用戶自己決定初始容量和加載因子,但這個初始容量不一定是HashMap真正的初始容量,下文會對此進行解釋
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()函數為其分配空間并計算真正的閾值
其他三種構造函數
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
當然在HashMap中有很多方法對AbstractMap的方法進行了覆蓋
下一節:HashMap的數據結構
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69987.html
摘要:當一個值中要存儲到的時候會根據的值來計算出他的,通過哈希來確認到數組的位置,如果發生哈希碰撞就以鏈表的形式存儲在源碼分析中解釋過,但是這樣如果鏈表過長來的話,會把這個鏈表轉換成紅黑樹來存儲。 正文開始 注:JDK版本為1.8 HashMap1.8和1.8之前的源碼差別很大 目錄 簡介 數據結構 類結構 屬性 構造方法 增加 刪除 修改 總結 1.HashMap簡介 H...
摘要:的工作原理是近年來常見的面試題。讓我們再來看看這些問題設計哪些知識點的概念中解決碰撞的方法和的應用,以及它們在中的重要性不可變對象的好處多線程的條件競爭重新調整的大小總結的工作原理基于原理,我們通過和方法儲存和獲取對象。 HashMap 的工作原理是近年來常見的 Java 面試題。幾乎每個 Java 程序員都知道 HashMap,都知道哪里要用 HashMap,知道Hashtable和...
摘要:根據的重新計算值。如果這兩個的通過比較返回,新添加的將覆蓋集合中原有的,但不會覆蓋。如果這兩個的通過比較返回,新添加的將與集合中原有形成鏈,而且新添加的位于鏈的頭部具體說明繼續看方法的說明。 關于hashCode hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用來在散列存儲結構中確定對象的存儲地址的. 1.hashcode是用來...
摘要:為了解決這個問題設計了一個閾值,其值為容量的,當所用容量超過了閾值后,就會自動擴充其容量。如果條件競爭發生了,那么就會產生死循環了。 由于HashMap的容量是有限的,如果HashMap中的數組的容量很小,假如只有2個,那么如果要放進10個keys的話,碰撞就會非常頻繁,此時一個O(1)的查找算法,就變成了鏈表遍歷,性能變成了O(n),這是Hash表的缺陷。 為了解決這個問題,Hash...
摘要:在二叉查找樹強制一般要求以外,對于任何有效的紅黑樹增加了如下的額外要求節點是紅色或黑色。紅黑樹有哪些應用場景內核和系統調用實現中使用的完全公平調度程序使用紅黑樹。 前言 這篇文章是記錄自己分析 Java 8 的 HashMap 源碼時遇到的疑問和總結,在分析的過程中筆者把遇到的問題都記錄下來,然后逐一擊破,如果有錯誤的地方,希望讀者可以指正,筆者感激不盡。 疑問與解答 什么是 initia...
閱讀 537·2021-10-19 11:45
閱讀 1346·2021-09-30 09:48
閱讀 1464·2021-08-16 10:56
閱讀 728·2021-07-26 23:38
閱讀 3207·2019-08-30 13:15
閱讀 2589·2019-08-30 12:45
閱讀 1823·2019-08-29 12:14
閱讀 2059·2019-08-26 18:42