Set幾乎都是內(nèi)部用一個Map來實現(xiàn), 因為Map里的KeySet就是一個Set,而value是假值崔步,全部使用同一個Object稳吮。Set的特征也繼承了那些內(nèi)部Map實現(xiàn)的特征。
HashSet
只去重復(fù)井濒,沒有順序灶似,不是同步,可存儲null瑞你,只能我存儲一個null酪惭。
HashSet的add方法會調(diào)用hashCode和equals, 所以如果要把一個對象放入HashSet中,重寫該對象對應(yīng)類的equals方法者甲,也應(yīng)該重寫其hashCode()方法春感。其規(guī)則是如果兩個對 象通過equals方法比較返回true時,其hashCode也應(yīng)該相同虏缸。另外鲫懒,對象中用作equals比較標(biāo)準的屬性,都應(yīng)該用來計算 hashCode的值刽辙。
如果我們希望一個集合有去重復(fù)的功能, 可以在它的add方法中檢查要添加的對象在集合中是否存在. 迭代集合中每個元素, 和要添加的比較, 如果相同, 就不存. 如果使用上述方法, 當(dāng)集合元素特別多的時候, 效率會很低.例如: 集合中有1萬個元素, 當(dāng)存儲下一個的時候, 需要和前面1萬個都比較, 效率較低窥岩。工作原理:
每次存儲對象的時候, 調(diào)用對象的hashCode()方法, 計算一個哈希值. 在集合中查找是否包含哈希值相同的元素。
如果沒有哈希值相同元素, 直接存入扫倡。
如果有哈希值相同的元素, 逐個使用equals()方法比較谦秧。
比較結(jié)果全為false就存入竟纳。
如果比較結(jié)果有true則不存。
如何將自定義類對象存入HashSet進行去重復(fù)疚鲤。
類中必須重寫hashCode()方法和equals()方法锥累。
equals()方法中比較所有屬性。
hashCode()方法要保證屬性相同的對象返回值相同, 屬性不同的對象盡量不同集歇。
LinkedHashSet
HashSet的子類, 去重復(fù), 并且保留存儲順序
LinkedHashSet在迭代訪問Set中的全部元素時桶略,性能比HashSet好,但是插入時性能稍微遜色于HashSet诲宇。
TreeSet
去重復(fù), 并且可以按照某種順序排序
TreeSet的add方法會將對象轉(zhuǎn)為Comparable, 然后調(diào)用compareTo方法, 所以存儲在TreeSet中的對象必須實現(xiàn)Comparable, 重寫compareTo方法际歼。TreeSet支持兩種排序方式,自然排序 和定制排序姑蓝。
(http://www.reibang.com/p/38a255477b08)
TreeSet存儲對象的時候, 可以排序, 但是需要指定排序的算法
Integer能排序(有默認順序), String能排序(有默認順序), 自定義的類存儲的時候出現(xiàn)異常(沒有順序)
?如果想把自定義類的對象存入TreeSet進行排序, 那么必須實現(xiàn)Comparable接口
在類上implement Comparable
重寫compareTo()方法
在方法內(nèi)定義比較算法, 根據(jù)大小關(guān)系, 返回正數(shù)負數(shù)或零
在使用TreeSet存儲對象的時候, add()方法內(nèi)部就會自動調(diào)用compareTo()方法進行比較, 根據(jù)比較結(jié)果使用二叉樹形式進行存儲
區(qū)別總結(jié):
一.HashSet
特點:
1.HashSet中不能有相同的元素鹅心,可以有一個Null元素,存入的元素是無序的纺荧。
2.HashSet如何保證唯一性旭愧?
1).HashSet底層數(shù)據(jù)結(jié)構(gòu)是哈希表,哈希表就是存儲唯一系列的表宙暇,而哈希值是由對象的hashCode()方法生成输枯。
2).確保唯一性的兩個方法:hashCode()和equals()方法。
3.添加占贫、刪除操作時間復(fù)雜度都是O(1)桃熄。
4.非線程安全
二.LinkedHashSet
特點:
1.LinkedHashSet中不能有相同元素,可以有一個Null元素型奥,元素嚴格按照放入的順序排列瞳收。
2.LinkedHashSet如何保證有序和唯一性?
1).底層數(shù)據(jù)結(jié)構(gòu)由哈希表和鏈表組成桩引。
2).鏈表保證了元素的有序即存儲和取出一致缎讼,哈希表保證了元素的唯一性。
3.添加坑匠、刪除操作時間復(fù)雜度都是O(1)血崭。
4.非線程安全
三.TreeSet
特點:
1.TreeSet是中不能有相同元素,不可以有Null元素厘灼,根據(jù)元素的自然順序進行排序夹纫。
2.TreeSet如何保證元素的排序和唯一性?
底層的數(shù)據(jù)結(jié)構(gòu)是紅黑樹(一種自平衡二叉查找樹)
3.添加设凹、刪除操作時間復(fù)雜度都是O(log(n))
4.非線程安全
四.總結(jié):
通過以上特點可以分析出舰讹,三者都保證了元素的唯一性,如果無排序要求可以選用HashSet闪朱;如果想取出元素的順序和放入元素的順序相同月匣,那么可以選用LinkedHashSet钻洒。如果想插入、刪除立即排序或者按照一定規(guī)則排序可以選用TreeSet锄开。
如果你想訪問set中的任意元素素标,無疑TreeSet是最快的,因為TreeSet已經(jīng)排序好了無需再遍歷整個數(shù)組或者是鏈表萍悴。所有的linked實現(xiàn)的結(jié)構(gòu)在訪問任意元素傻上都很慢头遭,但是在移動和替換元素上是很快的。
HashSet是大多內(nèi)存要求的癣诱,如果你有大量的RAM计维,并且在你的set中的讀寫的性能相對合理的話,那么HashSet是個不錯的選擇撕予。
http://blog.csdn.net/zhangwenjun32/article/details/8745431
http://blog.csdn.net/maoyeqiu/article/details/48766135
http://blog.csdn.net/u013256816/article/details/50917379
http://blog.csdn.net/stemq/article/details/66477615
http://blog.csdn.net/stemq/article/details/66477615