底層資料結構是雜湊表(元素是鍊錶的陣列),也就是說,保證元素的唯一性的第一層保證就是元素的hashcode。下面我們從原始碼的角度來分析:當我們向hashset中插入乙個元素的時候,發生了什麼。
public hashset()
這裡hashset的構造函式呼叫了hashmap,
public class hashmapextends abstractmapimplements map, cloneable, serializable
hashmap是乙個繼承了abstractmap的類,那麼我們來看看它實現了什麼
public v put(k key, v value)
}modcount++;
addentry(hash, key, value, i);
return null;
}
這是hashmap中的put方法,這裡的value暫時不管,檢視原始碼可以發現它似乎是隨機取的乙個物件位址而已,具體有什麼作用我也不清楚。
key是我們要插入hashmap的元素。假設這個元素為null時,則return putfornullkey(value)
private v putfornullkey(v value)
}modcount++;
addentry(0, null, value, 0);
return null;
}
這段**表示,假如我們傳入了乙個null,那麼putfornullkey會根據我們傳入null時附帶的value值去計算,hashset表的第乙個鍊錶是否為null,如果是null,則將我們這個(0, null, value, 0)插入其中,如果第乙個鍊錶不為null,就判斷其中的元素的key值是不是與null,如果是null,就說明,之前已經傳過乙個null的元素到hashset中了,則不再向第乙個鍊錶中增添元素,並且返回舊的null值所對應的value值。那這裡跟我們要理解的唯一性關係不大。
接下來回來put函式,put函式先根據我們傳入的key值,對其進行了hash運算,然後再根據hash值算出了索引i。索引i所對應的table中的鍊錶。然後for迴圈中依次對鍊錶中的元素的hash值進行檢查(因為不用呼叫到equals方法,所以比較高效,先進行),假如hash值相同,則再對元素的key值的引用位址或者用equals方法對key的真實內容進行比較。如果比較結果是key值已經存在於表中,那麼就不對其進行插入,而是返回原本的key值對應的value值。
如果這個表中的元素不存在key值相同的元素,那麼就將(hash, key, value, i)插入。
由以上原始碼的分析可以看出,唯一性的兩個保證是hash值還有equals方法,但是預設的equals方法只比較位址,所以要想真正實現唯一性,需要重寫equals方法。
HashSet 如何保證元素不重複 hash碼
hashset 不重複主要add 方法實現,使用 add 方法找到是否存在元素,存在就不新增,不存在就新增。hashset 主要是基於hashmap 實現的,hashmap 的key就是 hashset 的元素,hashset 基於hash 函式實現元素不重複。首先看 add 方法 public b...
HashSet保證元素唯一原理
1.hashset保證元素唯一原理 依賴於hashcode 和equals 方法 2.唯一原理 2.1 當hashset集合要儲存元素的時候,會呼叫該元素的hashcode 方法計算雜湊值 2.2 判斷該雜湊值對應的位置上,是否有元素 2.3 如果該雜湊值位置上沒有元素,那麼就直接儲存該元素 2.4...
HashSet保證元素唯一性
set儲存的資料是唯一性的,是通過儲存的物件的兩個方法進行唯一性判斷的hashcode 和equals 在呼叫集合的add e e 方法時,會進行判斷,通過e.hashcode 獲取要新增物件的hash值,和集合裡面的物件進行判斷,如果hash值不一樣,則會儲存。如果一樣,則會呼叫equals 方法...