HashSet
HashSet有以下特點
不能保證元素的排列順序,順序有可能發生變化
不是同步的
集合元素可以是null,但只能放入一個null
當向HashSet集合中存入一個元素時,HashSet會調用該對象的hashCode()方法來得到該對象的hashCode值,然后根據 hashCode值來決定該對象在HashSet中存儲位置。
簡單的說,HashSet集合判斷兩個元素相等的標准是兩個對象通過equals方法比較相等,並且兩個對象的hashCode()方法返回值相 等
注意,如果要把一個對象放入HashSet中,重寫該對象對應類的equals方法,也應該重寫其hashCode()方法。其規則是如果兩個對 象通過equals方法比較返回true時,其hashCode也應該相同。另外,對象中用作equals比較標准的屬性,都應該用來計算 hashCode的值。
TreeSet類
TreeSet是SortedSet接口的唯一實現類,TreeSet可以確保集合元素處於排序狀態。TreeSet支持兩種排序方式,自然排序 和定制排序,其中自然排序為默認的排序方式。向TreeSet中加入的應該是同一個類的對象。
TreeSet判斷兩個對象不相等的方式是兩個對象通過equals方法返回false,或者通過CompareTo方法比較沒有返回0
自然排序
自然排序使用要排序元素的CompareTo(Object obj)方法來比較元素之間大小關系,然后將元素按照升序排列。
Java提供了一個Comparable接口,該接口里定義了一個compareTo(Object obj)方法,該方法返回一個整數值,實現了該接口的對象就可以比較大小。
obj1.compareTo(obj2)方法如果返回0,則說明被比較的兩個對象相等,如果返回一個正數,則表明obj1大於obj2,如果是 負數,則表明obj1小於obj2。
如果我們將兩個對象的equals方法總是返回true,則這兩個對象的compareTo方法返回應該返回0
定制排序
自然排序是根據集合元素的大小,以升序排列,如果要定制排序,應該使用Comparator接口,實現 int compare(T o1,T o2)方法。
最重要:
1、TreeSet 是二叉樹實現的,TreeSet中的數據是自動排好序的,不允許放入null值。
2、HashSet 是哈希表實現的,HashSet中的數據是無序的,可以放入null,但只能放入一個null,兩者中的值都不能重復,就如數據庫中唯一約束。
3、HashSet要求放入的對象必須實現HashCode()方法,放入的對象,是以hashcode碼作為標識的,而具有相同內容的 String對象,hashcode是一樣,所以放入的內容不能重復。但是同一個類的對象可以放入不同的實例 。
HashSet與TreeSet的使用場景
HashSet:哈希表是通過使用稱為散列法的機制來存儲信息的,元素並沒有以某種特定順序來存放 TreeSet:提供一個使用樹結構存儲Set接口的實現(紅黑樹算法),對象以升序順序存儲,訪問和遍歷的時間很快。
使用場景:HashSet是基於Hash算法實現的,其性能通常都優於TreeSet。我們通常都應該使用HashSet,在我們需要排序的功能時,我們才使用TreeSet。
HashSet與TreeSet的底層運行方式:
TreeSet集合對象的加入過程:
TreeSet的底層是通過二叉樹來完成存儲的,無序的集合
當我們將一個對象加入TreeSet中,TreeSet會將第一個對象作為根對象,然后調用對象的compareTo方法拿第二個對象和第一個比較,當返回至=0時,說明2個對象內容相等,TreeSet就不把第二個對象加入集合。返回>1時,說明第二個對象大於第一個對象,將第二個對象放在右邊,返回-1時,則將第二個對象放在左邊,依次類推
HashSet集合對象的加入過程:
HashSet底層是hash值的地址,它里面存的對象是無序的。
第一個對象進入集合時,HashSet會調用object類的hashCode根據對象在堆內存里的地址調用對象重寫的hashCode計算出一個hash值,然后第一個對象就進入HashSet集合中的任意一個位置。
第二個對象開始進入集合,HashSet先根據第二個對象在堆內存的地址調用對象的計算出一個hash值,如果第二個對象和第一個對象在堆內存里的地址是相同的,那么得到的hash值也是相同的,直接返回true,hash得到true后就不把第二個元素加入集合(這段是hash源碼程序中的操作)。如果第二個對象和第一個對象在堆內存里地址是不同的,這時HashSet類會先調用自己的方法遍歷集合中的元素,當遍歷到某個元素時,調用對象的equals方法,如果相等,返回true,則說明這兩個對象的內容是相同的,HashSet得到true后不會把第二個對象加入集合。