亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

深入Java集合學習系列:HashSet的實現原理

系統 1745 0

1.??? HashSet 概述:

?? ? HashSet 實現 Set 接口,由哈希表(實際上是一個 HashMap 實例)支持。它不保證 set ? 的迭代順序;特別是它不保證該順序恒久不變。此類允許使用 null 元素。

?

2.??? HashSet 的實現:

?? ? 對于 HashSet 而言,它是基于 HashMap 實現的, HashSet 底層使用 HashMap 來保存所有元素,因此 HashSet ? 的實現比較簡單,相關 HashSet 的操作,基本上都是 直接調用底層 HashMap 的相關方法來完成 我們應該為保存到HashSet中的對象覆蓋hashCode()和equals(),因為再將對象加入到HashSet中時,會首先調用hashCode方法計算出對象的hash值,接著根據此hash值調用HashMap中的hash方法,得到的值& (length-1)得到該對象在hashMap的transient Entry[] table中的保存位置的索引,接著找到數組中該索引位置保存的對象,并調用equals方法比較這兩個對象是否相等,如果相等則不添加,如果不等,則添加到該數組索引對應的鏈表中。

------------------------------------------------------------------------------------------

Set的實現類的集合對象中不能夠有重復元素,HashSet也一樣他是使用了一種標識來確定元素的不重復,HashSet用一種算法來保證HashSet中的元素是不重復的,??? HashSet采用哈希算法,底層用數組存儲數據。 默認初始化容量16,加載因子0.75

?Object類中的hashCode()的方法是所有子類都會繼承這個方法,這個方法 會用Hash算法算出一個Hash(哈希)碼值返回,HashSet會用Hash碼值去和數組長度取模,?模(這個模就是對象要存放在數組中的位置)相同時才會判斷數組中的元素和要加入的對象的內容是否相同,如果不同才會添加進去。

?Hash算法是一種散列算法。

??Set hs=new HashSet();
?
??hs.add(o);
???? |
???????? o.hashCode();
???? |
??o%當前總容量? (0--15)
???? |???????????? ?
???? |?????????? 不發生沖突
??????? 是否發生沖突-----------------直接存放
???? |
???? | 發生沖突
???? |????????????? 假(不相等)
??????? o1.equals(o2)-------------------找一個空位添加
???? |
???? |? 是(相等)
???????? 不添加
?
?覆蓋hashCode()方法的原則:
? 1、一定要讓那些我們認為相同的對象返回相同的hashCode值
? 2、盡量讓那些我們認為不同的對象返回不同的hashCode值,否則,就會增加沖突的概率。
??3、盡量的讓hashCode值散列開(兩值用異或運算可使結果的范圍更廣)


?注意:所以 要存入HashSet的集合對象中的自定義類必須覆蓋hashCode(),equals()兩個方法 ,才能保證集合中元素不重復。在覆蓋equals()和hashCode()方法時,?要使相同對象的hashCode()方法返回相同值,覆蓋equals()方法再判斷其內容。為了保證效率,所以在覆蓋hashCode()方法時,?也要盡量使不同對象盡量返回不同的Hash碼值。

?如果數組中的元素和要加入的對象的hashCode()返回了相同的Hash值(相同對象),才會用equals()方法來判斷兩個對象的內容是否相同。

------------------------------------------------------------------------------------------

?

? HashSet 的源代碼如下:

Java代碼
  1. public ? class ?HashSet<E>??
  2. ???? extends ?AbstractSet<E>??
  3. ???? implements ?Set<E>,?Cloneable,?java.io.Serializable??
  4. {??
  5. ???? static ? final ? long ?serialVersionUID?=?-5024744406713321676L;??
  6. ??
  7. ???? //?底層使用HashMap來保存HashSet中所有元素。 ??
  8. ???? private ? transient ?HashMap<E,Object>?map;??
  9. ??????
  10. ???? //?定義一個虛擬的Object對象作為HashMap的value,將此對象定義為static?final。 ??
  11. ???? private ? static ? final ?Object?PRESENT?=? new ?Object();??
  12. ??
  13. ???? /** ?
  14. ?????*?默認的無參構造器,構造一個空的HashSet。 ?
  15. ?????*? ?
  16. ?????*?實際底層會初始化一個空的HashMap,并使用默認初始容量為16和加載因子0.75。 ?
  17. ?????*/ ??
  18. ???? public ?HashSet()?{??
  19. ????map?=? new ?HashMap<E,Object>();??
  20. ????}??
  21. ??
  22. ???? /** ?
  23. ?????*?構造一個包含指定collection中的元素的新set。 ?
  24. ?????* ?
  25. ?????*?實際底層使用默認的加載因子0.75和足以包含指定 ?
  26. ?????*?collection中所有元素的初始容量來創建一個HashMap。 ?
  27. ?????*?@param?c?其中的元素將存放在此set中的collection。 ?
  28. ?????*/ ??
  29. ???? public ?HashSet(Collection<?? extends ?E>?c)?{??
  30. ????map?=? new ?HashMap<E,Object>(Math.max(( int )?(c.size()/.75f)?+? 1 ,? 16 ));??
  31. ????addAll(c);??
  32. ????}??
  33. ??
  34. ???? /** ?
  35. ?????*?以指定的initialCapacity和loadFactor構造一個空的HashSet。 ?
  36. ?????* ?
  37. ?????*?實際底層以相應的參數構造一個空的HashMap。 ?
  38. ?????*?@param?initialCapacity?初始容量。 ?
  39. ?????*?@param?loadFactor?加載因子。 ?
  40. ?????*/ ??
  41. ???? public ?HashSet( int ?initialCapacity,? float ?loadFactor)?{??
  42. ????map?=? new ?HashMap<E,Object>(initialCapacity,?loadFactor);??
  43. ????}??
  44. ??
  45. ???? /** ?
  46. ?????*?以指定的initialCapacity構造一個空的HashSet。 ?
  47. ?????* ?
  48. ?????*?實際底層以相應的參數及加載因子loadFactor為0.75構造一個空的HashMap。 ?
  49. ?????*?@param?initialCapacity?初始容量。 ?
  50. ?????*/ ??
  51. ???? public ?HashSet( int ?initialCapacity)?{??
  52. ????map?=? new ?HashMap<E,Object>(initialCapacity);??
  53. ????}??
  54. ??
  55. ???? /** ?
  56. ?????*?以指定的initialCapacity和loadFactor構造一個新的空鏈接哈希集合。 ?
  57. ?????*?此構造函數為包訪問權限,不對外公開,實際只是是對LinkedHashSet的支持。 ?
  58. ?????* ?
  59. ?????*?實際底層會以指定的參數構造一個空LinkedHashMap實例來實現。 ?
  60. ?????*?@param?initialCapacity?初始容量。 ?
  61. ?????*?@param?loadFactor?加載因子。 ?
  62. ?????*?@param?dummy?標記。 ?
  63. ?????*/ ??
  64. ????HashSet( int ?initialCapacity,? float ?loadFactor,? boolean ?dummy)?{??
  65. ????map?=? new ?LinkedHashMap<E,Object>(initialCapacity,?loadFactor);??
  66. ????}??
  67. ??
  68. ???? /** ?
  69. ?????*?返回對此set中元素進行迭代的迭代器。返回元素的順序并不是特定的。 ?
  70. ?????*? ?
  71. ?????*?底層實際調用底層HashMap的keySet來返回所有的key。 ?
  72. ?????*?可見HashSet中的元素,只是存放在了底層HashMap的key上, ?
  73. ?????*?value使用一個static?final的Object對象標識。 ?
  74. ?????*?@return?對此set中元素進行迭代的Iterator。 ?
  75. ?????*/ ??
  76. ???? public ?Iterator<E>?iterator()?{??
  77. ???? return ?map.keySet().iterator();??
  78. ????}??
  79. ??
  80. ???? /** ?
  81. ?????*?返回此set中的元素的數量(set的容量)。 ?
  82. ?????* ?
  83. ?????*?底層實際調用HashMap的size()方法返回Entry的數量,就得到該Set中元素的個數。 ?
  84. ?????*?@return?此set中的元素的數量(set的容量)。 ?
  85. ?????*/ ??
  86. ???? public ? int ?size()?{??
  87. ???? return ?map.size();??
  88. ????}??
  89. ??
  90. ???? /** ?
  91. ?????*?如果此set不包含任何元素,則返回true。 ?
  92. ?????* ?
  93. ?????*?底層實際調用HashMap的isEmpty()判斷該HashSet是否為空。 ?
  94. ?????*?@return?如果此set不包含任何元素,則返回true。 ?
  95. ?????*/ ??
  96. ???? public ? boolean ?isEmpty()?{??
  97. ???? return ?map.isEmpty();??
  98. ????}??
  99. ??
  100. ???? /** ?
  101. ?????*?如果此set包含指定元素,則返回true。 ?
  102. ?????*?更確切地講,當且僅當此set包含一個滿足(o==null???e==null?:?o.equals(e)) ?
  103. ?????*?的e元素時,返回true。 ?
  104. ?????* ?
  105. ?????*?底層實際調用HashMap的containsKey判斷是否包含指定key。 ?
  106. ?????*?@param?o?在此set中的存在已得到測試的元素。 ?
  107. ?????*?@return?如果此set包含指定元素,則返回true。 ?
  108. ?????*/ ??
  109. ???? public ? boolean ?contains(Object?o)?{??
  110. ???? return ?map.containsKey(o);??
  111. ????}??
  112. ??
  113. ???? /** ?
  114. ?????*?如果此set中尚未包含指定元素,則添加指定元素。 ?
  115. ?????*?更確切地講,如果此?set?沒有包含滿足(e==null???e2==null?:?e.equals(e2)) ?
  116. ?????*?的元素e2,則向此set?添加指定的元素e。 ?
  117. ?????*?如果此set已包含該元素,則該調用不更改set并返回false。 ?
  118. ?????* ?
  119. ?????*?底層實際將將該元素作為key放入HashMap。 ?
  120. ?????*?由于HashMap的put()方法添加key-value對時,當新放入HashMap的Entry中key ?
  121. ?????*?與集合中原有Entry的key相同(hashCode()返回值相等,通過equals比較也返回true), ?
  122. ?????*?新添加的Entry的value會將覆蓋原來Entry的value,但key不會有任何改變, ?
  123. ?????*?因此如果向HashSet中添加一個已經存在的元素時,新添加的集合元素將不會被放入HashMap中, ?
  124. ?????*?原來的元素也不會有任何改變,這也就滿足了Set中元素不重復的特性。 ?
  125. ?????*?@param?e?將添加到此set中的元素。 ?
  126. ?????*?@return?如果此set尚未包含指定元素,則返回true。 ?
  127. ?????*/ ??
  128. ???? public ? boolean ?add(E?e)?{??
  129. ???? return ?map.put(e,?PRESENT)== null ;??
  130. ????}??
  131. ??
  132. ???? /** ?
  133. ?????*?如果指定元素存在于此set中,則將其移除。 ?
  134. ?????*?更確切地講,如果此set包含一個滿足(o==null???e==null?:?o.equals(e))的元素e, ?
  135. ?????*?則將其移除。如果此set已包含該元素,則返回true ?
  136. ?????*?(或者:如果此set因調用而發生更改,則返回true)。(一旦調用返回,則此set不再包含該元素)。 ?
  137. ?????* ?
  138. ?????*?底層實際調用HashMap的remove方法刪除指定Entry。 ?
  139. ?????*?@param?o?如果存在于此set中則需要將其移除的對象。 ?
  140. ?????*?@return?如果set包含指定元素,則返回true。 ?
  141. ?????*/ ??
  142. ???? public ? boolean ?remove(Object?o)?{??
  143. ???? return ?map.remove(o)==PRESENT;??
  144. ????}??
  145. ??
  146. ???? /** ?
  147. ?????*?從此set中移除所有元素。此調用返回后,該set將為空。 ?
  148. ?????* ?
  149. ?????*?底層實際調用HashMap的clear方法清空Entry中所有元素。 ?
  150. ?????*/ ??
  151. ???? public ? void ?clear()?{??
  152. ????map.clear();??
  153. ????}??
  154. ??
  155. ???? /** ?
  156. ?????*?返回此HashSet實例的淺表副本:并沒有復制這些元素本身。 ?
  157. ?????* ?
  158. <span
分享到:
評論

深入Java集合學習系列:HashSet的實現原理


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 操操操日日| 亚洲国产精品热久久2022 | 国产1区 | 欧美精品免费在线观看 | 涩涩综合| 俺去也理论网站 | 福利视频专区 | 久精品视频村上里沙 | 欧美日韩免费做爰视频 | 老色鬼久久综合第一 | 美女叫春 | 国产视频97| 深夜视频在线免费观看 | www.xxx欧美| 久久综合九色综合77 | 国产精品久久免费视频 | 国产欧美一区视频在线观看 | 九九九精品午夜在线观看 | 亚洲国产精品久久久天堂麻豆 | 日本一级毛片大片免费 | 瑟瑟视频在线观看 | 久久综合九色综合国产 | 欧美成人四级剧情在线播放 | 色综合色狠狠天天综合色 | 欧美精品国产 | 中文字幕综合网 | 美女视频黄的免费视频网页 | 成人小视频网 | 春暖花开亚洲 | 番茄视频成人在线观看 | 日本二区在线观看 | 国产综合91 | 亚洲精品免费在线 | 日韩在线观看视频网站 | 天天艹天天操 | 色拍999| 97视频在线观看视频在线精品 | 亚洲综合无码一区二区 | 国产午夜亚洲精品国产 | 日本精品久久久久中文字幕 1 | 久久机热re这里只有精品15 |