1. 程式人生 > >深入理解HashMap原理

深入理解HashMap原理

3、hashmap的resize 
       當hashmap中的元素越來越多的時候,碰撞的機率也就越來越高(因為陣列的長度是固定的),所以為了提高查詢的效率,就要對hashmap的陣列進行擴容,陣列擴容這個操作也會出現在ArrayList中,所以這是一個通用的操作,很多人對它的效能表示過懷疑,不過想想我們的“均攤”原理,就釋然了,而在hashmap陣列擴容之後,最消耗效能的點就出現了:原陣列中的資料必須重新計算其在新陣列中的位置,並放進去,這就是resize。 

         那麼hashmap什麼時候進行擴容呢?當hashmap中的元素個數超過陣列大小*loadFactor時,就會進行陣列擴容,loadFactor的預設值為0.75,也就是說,預設情況下,陣列大小為16,那麼當hashmap中元素個數超過16*0.75=12的時候,就把陣列的大小擴充套件為2*16=32,即擴大一倍,然後重新計算每個元素在陣列中的位置,而這是一個非常消耗效能的操作,所以如果我們已經預知hashmap中元素的個數,那麼預設元素的個數能夠有效的提高hashmap的效能。比如說,我們有1000個元素new HashMap(1000), 但是理論上來講new HashMap(1024)更合適,不過上面annegu已經說過,即使是1000,hashmap也自動會將其設定為1024。 但是new HashMap(1024)還不是更合適的,因為0.75*1000 < 1000, 也就是說為了讓0.75 * size >1000, 我們必須這樣new HashMap(2048)才最合適,既考慮了&的問題,也避免了resize的問題。 


4、key的hashcode與equals方法改寫 

在第一部分hashmap的資料結構中,annegu就寫了get方法的過程:首先計算key的hashcode,找到陣列中對應位置的某一元素,然後通過key的equals方法在對應位置的連結串列中找到需要的元素。所以,hashcode與equals方法對於找到對應元素是兩個關鍵方法。 

Hashmap的key可以是任何型別的物件,例如User這種物件,為了保證兩個具有相同屬性的user的hashcode相同,我們就需要改寫hashcode方法,比方把hashcode值的計算與User物件的id關聯起來,那麼只要user物件擁有相同id,那麼他們的hashcode也能保持一致了,這樣就可以找到在hashmap陣列中的位置了。如果這個位置上有多個元素,還需要用key的equals方法在對應位置的連結串列中找到需要的元素,所以只改寫了hashcode方法是不夠的,equals方法也是需要改寫滴~當然啦,按正常思維邏輯,equals方法一般都會根據實際的業務內容來定義,例如根據user物件的id來判斷兩個user是否相等。 
在改寫equals方法的時候,需要滿足以下三點: 
(1) 自反性:就是說a.equals(a)必須為true。 
(2) 對稱性:就是說a.equals(b)=true的話,b.equals(a)也必須為true。 
(3) 傳遞性:就是說a.equals(b)=true,並且b.equals(c)=true的話,a.equals(c)也必須為true。 
通過改寫key物件的equals和hashcode方法,我們可以將任意的業務物件作為map的key(前提是你確實有這樣的需要)。 

總結: 

    本文主要描述了HashMap的結構,和hashmap中hash函式的實現,以及該實現的特性,同時描述了hashmap中resize帶來效能消耗的根本原因,以及將普通的域模型物件作為key的基本要求。尤其是hash函式的實現,可以說是整個HashMap的精髓所在,只有真正理解了這個hash函式,才可以說對HashMap有了一定的理解。 

相關推薦

深入理解HashMap原理

3、hashmap的resize        當hashmap中的元素越來越多的時候,碰撞的機率也就越來越高(因為陣列的長度是固定的),所以為了提高查詢的效率,就要對hashmap的陣列進行擴容,陣列擴容這個操作也會出現在ArrayList中,所以這是一個通用的操作,很多人對它的效能表示過懷疑,不過想想我們

深入理解HashMap原理,查詢,擴容)

面試的時候聞到了Hashmap的擴容機制,之前只看到了Hasmap的實現機制,補一下基礎知識,講的非常好 原文連結: Hashmap是一種非常常用的、應用廣泛的資料型別,最近研究到相關的內容,就正好複習一下。網上關於hashmap的文章很多,但到底是自己學習的總結,就

深入理解HashMap(及hash函數的真正巧妙之處)

ssa 什麽 關聯 表示 廣泛 要求 傳遞 所有 總結 原文地址:http://www.iteye.com/topic/539465 Hashmap是一種非常常用的、應用廣泛的數據類型,最近研究到相關的內容,就正好復習一下。網上關於hashmap的文章很多,但到底是自己

深入理解 HashMap

包含 刪除 不同 鍵值 code 1.8 信息 索引 導致 1. 簡介 HashMap 是Java開發中使用頻率最高的鍵值對數據類型容器。它根據鍵的哈希值(hashCode)來存儲數據,訪問速度高,但無法按照順序遍歷。HashMap 允許鍵值為空和記錄為空,非線程安全。 另

深入理解HashMap及面試相關問答

前言 HashMap是面試必備的一個知識點,無論你是初級中級還是高階,基本上逃不過這個問題,下面的內容很簡單,只要你理解了其中的含義,這對你使用hashmap和麵試都是很有幫助的。 正文 首先開啟HashMap,看看中都定義了哪些成員變數。 解釋幾個重點的變數 transi

深入理解mysqldump原理 --single-transaction --lock-all-tables --master-data

在mysqldump過程中,之前其實一直不是很理解為什麼加了--single-transaction就能保證innodb的資料是完全一致的,而myisam引擎無法保證,必須加--lock-all-tables,前段時間抽空詳細地查看了整個mysqldump過程。 理解master-data和--

深入理解hashmap理論篇

之前有過一篇介紹java中hashmap使用的,深入理解hashmap,比較側重於 程式碼分析,沒有從理論上分析hashmap,今天把hashmap的理論部分補充一下(之後應該還有兩篇補充 一篇講紅黑樹一篇講多執行緒)。 雜湊(雜湊)函式到底是幹嘛的?和雜湊表是啥關係?其主要作用和應用場景到底在哪裡? 簡

深入理解hashmap(三)雜湊表和二叉搜尋樹的恩怨情仇

前面兩篇文章介紹了hashmap的原始碼和理論,今天把剩餘的部分紅黑樹講一下。理解好紅黑樹,對我們後續對hashmap或者其他資料結構的理解都是很有好處的。比方說為什麼後面jdk要把hashmap中的單鏈表更新成紅黑樹? 要理解紅黑樹首先要弄清楚普通二叉樹的一些基本概念 父節點和子節點,這個我就不多說了。

記憶體系列二:深入理解硬體原理

本篇文章承接上文繼續介紹DDR記憶體的硬體原理,包括如何定址,時序和時延以及可以為提高記憶體的效能可以有哪些方法。 上次雖然解決了小張的問題,卻引發了他對記憶體原理的興趣。這不他又來找我了,說我還欠他一個解釋。這次我們約在一個咖啡館見面,這次內容有點深入,我帶了些圖片,小張也點了一大杯美式,計劃大幹一

深入理解HashMap(一次性徹底掌握)

Hashmap是一種非常常用的、應用廣泛的資料型別,最近研究到相關的內容,就正好複習一下。網上關於hashmap的文章很多,但到底是自己學習的總結,就發出來跟大家一起分享,一起討論。  1、hashmap的資料結構  要知道hashmap是什麼,首先要搞清楚它的資料結構,在j

深入理解mybatis原理》 MyBatis快取機制的設計與實現

本文主要講解MyBatis非常棒的快取機制的設計原理,給讀者們介紹一下MyBatis的快取機制的輪廓,然後會分別針對快取機制中的方方面面展開討論。 MyBatis將資料快取設計成兩級結構,分為一級快取、二級快取:       &nb

深入理解mybatis原理》 MyBatis的二級快取的設計原理

       MyBatis的二級快取是Application級別的快取,它可以提高對資料庫查詢的效率,以提高應用的效能。本文將全面分析MyBatis的二級快取的設計原理。 1.MyBatis的快取機制整體設計以及二級快取的工作模式  

深入理解HashMap(及hash函式的真正巧妙之處)

Hashmap是一種非常常用的、應用廣泛的資料型別,最近研究到相關的內容,就正好複習一下。網上關於hashmap的文章很多,但到底是自己學習的總結,就發出來跟大家一起分享,一起討論。  1、hashmap的資料結構  要知道hashmap是什麼,首先要搞清楚它的資料結

從原始碼深入理解HashMap(附加HashMap面試題)

HashMap向來是面試中的熱點話題,深入理解了HashMap的底層實現後,才能更好的掌握它,也有利於在專案中更加靈活的使用。 本文基於JDK8進行解析 一、HashMap解析 1. 結構 HashMap結構由陣列加**連結串列(或紅黑樹)**構成。主幹是E

深入理解計算機原理——程式與執行(二)

浮點數 (1)       浮點數的表示方法; (2)       浮點數的精度與範圍; (3)       浮點數的分佈; (4)       浮點數階碼的表示方法; (5)       浮點數位數規格化; (6)       結合例子學習浮點數的表示方法; (7)       IEEE 754標準; 2

簡述JAVA GC回收機制,深入理解GC原理

什麼是“GC” 垃圾回收機制。 為什麼要用“GC” 眾所周知,JAVA 這語言,與C語言不同,Java記憶體(堆記憶體)的分配與回收由JVM垃圾收集器自動完成,比如 C語言自己定義的變數,不用時需要 自己回收這個變數 。JAVA 這就是自動完成了,自動檢測,無用的

深入理解PHP原理之Opcodes

最近要給Yahoo的同事們做一個關於PHP和Apache處理請求的內部機制的講座,剛好寫了些關於Opcodes的文字,就發上來了,這個文章基於 Sara Golemon大師的《Understanding OPcode》 Opcode是一種PHP指令碼編譯後的中間語言,就像Java的Byt

深入理解HashMap(精華必看)

3、hashmap的resize         當hashmap中的元素越來越多的時候,碰撞的機率也就越來越高(因為陣列的長度是固定的),所以為了提高查詢的效率,就要對hashmap的陣列進行擴容,陣列擴容這個操作也會出現在ArrayList中,所以這是一個通用的操作,很多人對它的效能表示過懷疑,不過想想我

深入理解Memcached原理

1.為什麼要使用memcache  由於網站的高併發讀寫需求,傳統的關係型資料庫開始出現瓶頸,例如: 1)對資料庫的高併發讀寫: 關係型資料庫本身就是個龐然大物,處理過程非常耗時(如解析SQL語句,事務處理等)。如果對關係型資料庫進行高併發讀寫(每秒上萬次的訪問),那麼它是

深入理解mybatis原理(三)》 MyBatis的一級快取實現詳解 及使用注意事項

0.寫在前面         MyBatis是一個簡單,小巧但功能非常強大的ORM開源框架,它的功能強大也體現在它的快取機制上。MyBatis提供了一級快取、二級快取 這兩個快取機制,能夠很好地處理和維護快取,以提高系統的效能。本文的目的則是向讀者詳細介紹MyBatis的一級快取,深入原始碼,解析MyBa