在Java的Set體系中,根據實現方式不同主要分為兩大類。HashSet和TreeSet。
1、TreeSet 是二叉樹實現的,Treeset中的數據是自動排好序的,不允許放入null值
2、HashSet 是哈希表實現的,HashSet中的數據是無序的,可以放入null,但只能放入一個null,兩者中的值都不能重復,就如數據庫中唯一約束
在HashSet中,基本的操作都是有HashMap底層實現的,因為HashSet底層是用HashMap存儲數據的。當向HashSet中添加元素的時候,首先計算元素的hashcode值,然后通過擾動計算和按位與的方式計算出這個元素的存儲位置,如果這個位置位空,就將元素添加進去;如果不為空,則用equals方法比較元素是否相等,相等就不添加,否則找一個空位添加。
TreeSet的底層是TreeMap的keySet(),而TreeMap是基於紅黑樹實現的,紅黑樹是一種平衡二叉查找樹,它能保證任何一個節點的左右子樹的高度差不會超過較矮的那棵的一倍。
TreeMap是按key排序的,元素在插入TreeSet時compareTo()方法要被調用,所以TreeSet中的元素要實現Comparable接口。TreeSet作為一種Set,它不允許出現重復元素。TreeSet是用compareTo()來判斷重復元素的。
HashSet實現原理?
1.基於HashMap實現的,默認構造函數是構建一個初始容量為16,負載因子為0.75 的HashMap。封裝了一個 HashMap 對象來存儲所有的集合元素,所有放入 HashSet 中的集合元素實際上由 HashMap 的 key 來保存,而 HashMap 的 value 則存儲了一個 PRESENT,它是一個靜態的 Object 對象。
2.當我們試圖把某個類的對象當成 HashMap的 key,或試圖將這個類的對象放入 HashSet 中保存時,重寫該類的equals(Object obj)方法和 hashCode()方法,而且這兩個方法的返回值必須保持一致:當該類的兩個的 hashCode() 返回值相同時,它們通過 equals() 方法比較也應該返回 true。
通常來說,所有參與計算 hashCode() 返回值的關鍵屬性,都應該用於作為 equals() 比較的標准。
3.HashSet的其他操作都是基於HashMap的。
總結:
Set 存儲自定義類型元素,並要去除重復的元素時,需要在該元素中重寫 HashCode 方法和 equals 方法。
