HashSet實現元素物件不可重複的原理(過程)

2021-10-07 11:27:00 字數 2253 閱讀 3412

現場景如下:

我們有乙個學生類,其成員變數如下:

private string name;

private

char ***;

private integer age;

private double score;

提供有參構造方法

public

student

(string name,

char ***, integer age, double score)

我們建立乙個hashset物件,然後建立兩個學生物件新增進去,最後我們輸出一下該set的大小

不難想象,結果為"2",即此時hashset將其作為了兩個不同的物件存了進去

下面我們重寫其hashcode方法與equals方法(編譯器預設)

@override

public

inthashcode()

@override

public

boolean

equals

(object obj)

elseif(

!age.

equals

(other.age)

)return

false;if

(name == null)

elseif(

!name.

equals

(other.name)

)return

false;if

(score == null)

elseif(

!score.

equals

(other.score)

)return

false;if

(*** != other.***)

return

false

;return

true

;}

現在我們有乙個需求,如果所新增學生的年齡不超過5歲,成績不超過10分,我們就將其作為同一物件,換言之就是在hashset中不能重複新增,我們該如何實現呢?

這就需要我們知道hashset是如何判斷物件是否唯一的標準

是物件的equals方法嗎?

我們修改equals方法如下:

新增物件如下

可是還是失敗了,輸出結果依然為"2",可見equals方法並沒有作為該依據,但是真的是這樣嗎?通過後續發現,其實不然,equals方法其實是作為其判斷的第二步的,那第一步是什麼呢?

是hashcode方法

我們看一下原本的hashcode方法

可見其所有引數都參與的運算,最起碼我們可以想象到其返回值絕對不是乙個相同的值

那我門將其返回值固定,結果會怎樣呢?

不出所然,成功了

hashset將其作為了同一物件

如果我們將equals方法如果復原,則其又新增上了

**溫柔一點:

上述直接定義hashcode()方法的返回值的操作太粗魯了,我們應該將其它元素考慮進去,即name屬性值與***屬性值應參加進去,**如下:

總結:

hashset在新增物件的時候,判斷其是否為同一元素物件的過程分為兩步

第一步: 呼叫物件的hashcode()方法,如果返回值不同,即為不同物件,直接新增成功

第二步: 呼叫物件的equals()方法,我們的需求條件需要在此處進行修改

HashSet不可以儲存相同元素的原理

雜湊表是以陣列加鍊表加紅黑樹來儲存資料的。當相同雜湊值的元素大於等於8個時 即雜湊衝突的元素超過8個 就會使用紅黑樹來儲存,因為紅黑樹查詢效率很高。雜湊表的儲存是首先通過雜湊函式來計算雜湊值 hashcode 來確定你要放到雜湊表裡面的哪乙個位置。這裡有乙個問題是 兩個元素會出現相同的雜湊值,至於為...

HashSet刪除重複元素

應用場景 經常遇到網路請求回來的資料是乙個list形式的列表,這個list的資料型別是自己定義的資料型別,這裡面包含了重複元素,而重複元素的判斷重複的標準往往是自己定義資料型別的某個成員變數來區分,比如,返回的是裝置資訊,則會有乙個對應的裝置id欄位,如果是人物資訊,返回註冊手機號等等。如果通過fo...

hashset儲存不重複元素的基本實現

hashset的實現原理 往haset新增元素的時候,hashset會先呼叫元素的hashcode方法得到元素的雜湊值 然後通過元素 的雜湊值經過移位等運算,就可以算出該元素在雜湊表中 的儲存位置。情況1 如果算出元素儲存的位置目前沒有任何元素儲存,那麼該元素可以直接儲存到該位置上。情況2 如果算出...