hashMap 源碼解讀理解實現原理和hash沖突

hashMap 怎么說呢。 我的理解是 外表是一個set 數組,無序不重復 。 每個set元素是一個bean ,存著一對key value

?

看看代碼吧

package test;import java.util.HashMap;
import java.util.Map.Entry;public class HashMaptest {public static void main(String[] args) {HashMap<String, String> map = new HashMap<String, String>();String aa = "張三";String bb = "李四";map.put(aa, "22");map.put(bb, "34234");map.put("張三", "223");System.out.println(aa.hashCode());System.out.println(bb.hashCode());for (Entry<String, String> entry : map.entrySet()) {System.out.println(entry.getKey());// System.out.println(entry.getValue());
        }}}

打印的結果是:

774889
842061
李四
張三

可以看到, 雖然張三是先插進去的, 但是確在后面打印出來,說明這個數組不是有序的, 不是list;

雖然aa? 的 hashcode=774889 大于bb 的, 肯定不是根據大小插入的,應該是把 得到的hashcode 取余 , 例如? 6%7 = 6 , 9%(7+1)=1 ,6>1? ,所以9 在前面,這里為什么是? 第一個除以7 ,第二個進來確實% 8呢;

因為hash算法是 這樣的:

int hash = key.hashCode(); // 這個hashCode方法這里不詳述,只要理解每個key的hash是一個固定的int值
int index = hash % Entry[].length;
Entry[index] = value;

這里看到? Entry[].length 一直在增加的;

?

所以就會遇到hash沖突, 總有碰到取余后一樣的;

好了,舉個例子:

比如 key="張三", hashcode=666 ,entry的size是 100 ? 666%100=66? ;存在? 66 位置上。? 這個時候 key="李四" 要插入了, hashcode =6666 entry的size是 6600? 6666%6600=66 , 這樣 66 位置就hash沖突了;

這里和我代碼寫的覆蓋不是一回事 。 代碼的 key? 相同,這里在特別說明下:可能有人說, 兩個張三的hashcode 一樣, 不同時候插入,entry 的 size不是不一樣嗎, 那就不會覆蓋了? 這么想是錯誤的, 其實 map 插入的時候是先比較equals? 的, 發現,咦 ,相同, 直接覆蓋原值

:附上 hashMap的Put 方法源碼:

?

   final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i;if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;if ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);else {Node<K,V> e; K k;if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))e = p;else if (p instanceof TreeNode)e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);else {for (int binCount = 0; ; ++binCount) {if ((e = p.next) == null) {p.next = newNode(hash, key, value, null);if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);break;}if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))break;p = e;}}if (e != null) { // existing mapping for keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value;afterNodeAccess(e);return oldValue;}}++modCount;if (++size > threshold)resize();afterNodeInsertion(evict);return null;}

?

?

?

可能比較難懂, 主要在這句:

??? if (e != null) { // existing mapping for key
??????????????? V oldValue = e.value;
??????????????? if (!onlyIfAbsent || oldValue == null)
??????????????????? e.value = value;
??????????????? afterNodeAccess(e);
??????????????? return oldValue;
??????????? }

已存在的key ,之而立是直接覆蓋的。

?

轉載于:https://www.cnblogs.com/zgghb/p/6385774.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371548.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371548.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371548.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

浙江大學linux網絡通信,浙江大學鐘財軍副教授——“Wireless Powered Communication Networks”...

2016年5月17日&#xff0c;浙江大學鐘財軍副教授應徐正元教授邀請在中科大西區科技實驗樓東樓十層1011會議室做了一場題為“Wireless Powered Communication Networks”的學術報告。報告會由龔晨教授主持&#xff0c;共50余名師生參加。此次報告會得到了“中科院無線光電通信重…

自定義Spring Data JPA存儲庫

Spring Data是一個非常方便的庫。 但是&#xff0c;由于該項目是一個相當新的項目&#xff0c;因此功能不佳。 默認情況下&#xff0c;Spring Data JPA將基于SimpleJpaRepository提供DAO的實現。 在最近的項目中&#xff0c;我開發了一個定制的存儲庫基類&#xff0c;以便可以在…

[基礎]PeopleSoft中的作業和調度作業集合定義

PeopleSoft進程調度器可以使一個或多個進程作為一個組。這個組在PeopleSoft中被稱為作業(Job)。 PeopleSoft進程被定義為單個任務&#xff0c;程序或例程&#xff0c;例如cobol程序或AE程序或客戶端運行的SQR。 作業由一個或多個相同或不同類型的進程組成&#xff0c;他們作為一…

體驗 WebFont,網頁上的藝術字

在最新項目中&#xff0c;由于要頻繁使用藝術字&#xff0c;而用戶設備沒有此字體&#xff0c;因此以往的經驗都是使用圖片...所以在同事的矚目期許之下&#xff0c;我開始實驗研究這個問題的解決方案1. 直接使用字體文件font-face {font-family: xxxx;src: url(../img/漢儀秀英…

linux文件分別打包命令,Linux文件打包命令

15.1 gzipgzip(1)是GNU的壓縮程序。它只對單個文件進行壓縮。基本用法如下&#xff1a;$ gzip filename程序執行以后&#xff0c;文件名會變成filename.gz&#xff0c;而且一般情況下大小會比原文件要小。注意&#xff0c;程序并不新建一個新的文件filename.gz,而是將filename變…

Play 2.0框架和XA交易

XA事務非常有用&#xff0c;而且開箱即用&#xff0c;今天的Play 2.0不支持它們。 在這里&#xff0c;我展示了如何添加該支持&#xff1a; 首先&#xff0c;介紹一些XA有用的示例&#xff1a; –如果您使用來自兩個不同persistence.xml的實體&#xff0c;則JPA使用兩個物理連…

java代碼注釋規范

java代碼注釋規范 一、規范存在的意義 應用編碼規范對于軟件本身和軟件開發人員而言尤為重要&#xff0c;有以下幾個原因&#xff1a;1、好的編碼規范可以盡可能的減少一個軟件的維護成本 , 并且幾乎沒有任何一個軟件&#xff0c;在其整個生命周期中&#xff0c;均由最初的開…

win10 hyper-v 虛擬機ping不通宿主機問題

在Windows10 Hyper-V 中安裝 Linux (Centos6.9)虛擬機無法 ping 通宿主機 這種情況下關閉 Windows 防火墻就能ping通了&#xff0c;當然關閉防火墻不安全。所以需要 做以下步驟: 控制面板-》系統和安全-》Windows防火墻-》高級設置-》入站規則 啟用下圖被紅框選中的兩個選…

linux方法參數,Linux的sysctl?命令?參數

Linux內核通過/proc虛擬文件系統向用戶導出內核信息&#xff0c;用戶也可以通過/proc文件系統或通過sysctl命令動態配置內核。比如&#xff0c;如果我們想啟動NAT&#xff0c;除了加載模塊、配置防火墻外&#xff0c;還需要啟動內核轉發功能。我們有三種方法&#xff1a;1. 直接…

Java枚舉:您擁有優雅,優雅和力量,這就是我所愛!

當Java 8即將面世時&#xff0c;您確定您對Java 5中引入的枚舉很了解嗎&#xff1f; Java枚舉仍然被低估了&#xff0c;很可惜&#xff0c;因為它們比您想象的要有用&#xff0c;它們不僅僅用于通常的枚舉常量&#xff01; Java枚舉是多態的 Java枚舉是可以包含行為甚至數據的…

C#刪除和清空文件夾的程序

/// <summary>/// 清空指定的文件夾&#xff0c;但不刪除文件夾/// </summary>/// <param name"dir"></param>private void DeleteFolder(string dir){foreach (string d in Directory.GetFileSystemEntries(dir)){if (File.Exists(d)){try{…

2)網頁請求順序

&#xff08;1&#xff09;分析瀏覽器訪問一個網頁的完整流程邏輯過程&#xff1a;http&#xff1a;//www.abc.com/def/ 轉載于:https://www.cnblogs.com/xiaoyoucai/p/7306246.html

JavaOne 2012:非阻塞數據結構如何工作?

當我查看今天的日程安排時&#xff0c;我感到有些驚訝&#xff0c;并指出我目前計劃今天參加的所有會議都在希爾頓舉行。 當我意識到JavaOne演示文稿中大約有一半是在希爾頓酒店中并且似乎按路線大致定位時&#xff0c;這變得有些不足為奇了。 Tobias Lindaaker &#xff08; 新…

c語言箭頭指針的作用,C語言中,結構體成員變量的點和箭頭

C語言中&#xff0c;調用成員變量用點還是用箭頭&#xff0c;取決于當前的ID是指針還是結構體本身。如&#xff1a;typedef struct {float height;float weight;} Person;int main(int argc, char *argv[]) {Person jiushen;Person *lengleng (Person *)malloc(sizeof(Person)…

JavaOne 2012:調查JVM水晶球

我回到了希爾頓的A / B廣場參加星期一的第四屆會議&#xff0c;但首先去了希爾頓的頂層收拾午餐。 我每年都在JavaOne的第一天被提醒&#xff0c;涉及到每個人的第一天的午餐獲取過程令人驚訝地令人沮喪。 我知道我在JavaOne的第一年的經歷使我有些困惑&#xff0c;因為我不確定…

測試遇到的問題

多人合作測試 多人員合作測試&#xff0c;應盡量保證測試平臺統一&#xff0c;處理流程統一&#xff0c;相互之間保持實時溝通。問題的處理進度應保證所負責的所有測試人員第一時間實時更新。 多人測試應做到2人或以上進行交叉測試。 轉載于:https://www.cnblogs.com/liuliu-wo…

Jquery Memo

jQuery選擇器 $( "#id" ) $( ".class" )$( "element" )全選擇器&#xff08;*選擇器&#xff09; * {padding: 0; margin: 0;}//子選擇器 //$(div > p) 選擇所有div元素里面的子元素P//后代選擇器 //$(div p) 選擇所有div元素…

c#語言輸出字符串長度,C#統計字符長度(漢字占2個字符)

在C#編程過程中&#xff0c;通過String類的Length屬性可以獲取對應字符串的長度&#xff0c;但是細心的讀者可能注意到了&#xff0c;String類的Length屬性返回的是字符串中Char對象的個數&#xff0c;也就是說&#xff0c;一個漢字的長度為1&#xff0c;對此&#xff0c;MSDN的…

使用JMSTester對JMS層進行基準測試

對于我去過的大多數客戶端&#xff0c;使用ActiveMQ擴展JMS消息傳遞層是一個優先事項。 有多種方法可以實現這一目標&#xff0c;但毫無疑問&#xff0c;創建基準測試并在實際硬件上分析架構&#xff08;或者正如我的同事Gary Tully所說的“詢問機器”&#xff09;是第一步。 但…

Js引擎解析執行 閱讀筆記

Js引擎解析執行 閱讀筆記 一篇閱讀筆記http://km.oa.com/group/2178/articles/show/145691?kmrefsearch&from_page1&no1 早期:遍歷語法樹 Js引擎最早使用的是遍歷語法樹方式 &#xff08;syntax tree walker&#xff09; 分為兩步 詞法分析語法分析詞法分析 i a b *…