iT邦幫忙

2021 iThome 鐵人賽

DAY 16
0
自我挑戰組

Java SE系列 第 16

Day16:請說出暗號證明你的身份

  • 分享至 

  • xImage
  •  

始祖巨人中我們條列出了所有Java物件都會繼承自Object類別的共同方法,這篇會提到其中的hashCode()與equals()這兩個方法如何在HashSet中被拿來運用。

若我們想要把數值或物件裝在一個東西之中,最常用的就是陣列(Array)了,不過除了陣列以外其實還有很多這種可以儲存數值或物件的東西,在Java中統稱為集合(Collection),集合底下有許多種的實作API供Java Programmer直接使用,這篇要來談的是HashSet。

HashSet是可以直接創建實例使用的類別,實作了Set介面。

Set的特性就是只能存在不重複的數值或物件,所以如果有一個陣列[1, 1, 2, 3],把他丟到一個Set時,這個Set只會存在[1, 2, 3]。

而既然Set是一個介面,就表示Java底下還有其他實作的Set類別可以用,例如TreeSet。每種Set類別都有其獨特的運作機制,視程式的情況來決定要使用哪種Set,而通常最常用的就是HashSet了。

HashSet不保證內容物的順序性,只確保了這裡面一定擁有不重複的數值或物件。那實際上是怎麼辦到的呢?就是利用了Object類別中的hashCode()與equals()這兩個方法。

在我們把東西加進HashSet後,HashSet會先做第一件事情:檢查我當前HashSet的元素中,有沒有和正要加進來的東西有同樣的HashCode,如果沒有的話,沒問題,就是直接加入到了HashSet成功;若有相同的HashCode...

就會做第二件事情:呼叫擁有相同HashCode物件的equals()方法,看回傳值是不是為false,false的話那一樣會把它加進HashSet之中;true的話,很抱歉,HashSet就不會把它加進來。

若我們再說的細一點,HashSet之中有個叫做Hash Bucket的資料結構,它就像是一個Map,有key以及key對應的value,Hash Code就是Hash Bucket的key,而value的部分就像是一個LinkedList,先前提到若是HashCode相同但是equals()方法又會回傳false,那就會在原本已存在元素的節點,next屬性上加入下一個節點,並放入新加入的元素。(若你看不懂這段,可以看看這篇)

看到這邊可能會對hash code與equals()的結果有些打結的狀況,其實大部分情況hash code一致的情形,equals()也會回傳true的,但在資料結構的規則中就會允許這樣的情況發生,而有這樣對應的處理。

以下幫大家做個小結:

  1. 若是物件要做比較,我們知道要在物件的類別中覆寫(override) equals()方法;但也別忘了覆寫hashCode()方法,因為若要用到HashSet時,就會需要用到hashCode()方法。
  2. 2個物件實例有相同的HashCode時,有可能equals方法比較後回傳false
  3. 2個物件實例的equals比較後回傳true,其Hash Code也要是一致

上一篇
Day15:刀槍與弓箭
下一篇
Day17:比大小
系列文
Java SE30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言