Java中HashSet、LinkedHashSet和TreeSet區(qū)別詳解
HashSet、LinkedHashSet、TreeSet區(qū)別
如果你需要一個(gè)訪問(wèn)快速的Set,你應(yīng)該使用HashSet;當(dāng)你需要一個(gè)排序的Set,你應(yīng)該使用TreeSet;當(dāng)你需要記錄下插入時(shí)的順序時(shí),你應(yīng)該使用LinedHashSet。
HashSet是采用hash表來(lái)實(shí)現(xiàn)的。其中的元素沒(méi)有按順序排列,add()、remove()以及contains()等方法都是復(fù)雜度為O(1)的方法。
TreeSet是采用樹(shù)結(jié)構(gòu)實(shí)現(xiàn)(紅黑樹(shù)算法)。元素是按順序進(jìn)行排列,但是add()、remove()以及contains()等方法都是復(fù)雜度為O(log (n))的方法。
它還提供了一些方法來(lái)處理排序的set,如first(), last(), headSet(), tailSet()等等。
LinkedHashSet介于HashSet和TreeSet之間。它也是一個(gè)hash表,但是同時(shí)維護(hù)了一個(gè)雙鏈表來(lái)記錄插入的順序?;痉椒ǖ膹?fù)雜度為O(1)。
一、HashSet
- 不能保證元素的排列順序,順序有可能發(fā)生變化
- 不是同步的,非線程安全
- 集合元素可以是null,但只能放入一個(gè)null
- 當(dāng)向HashSet結(jié)合中存入一個(gè)元素時(shí),HashSet會(huì)調(diào)用該對(duì)象的hashCode()方法來(lái)得到該對(duì)象的hashCode值,然后根據(jù) hashCode值來(lái)決定該對(duì)象在HashSet中存儲(chǔ)位置。
- 簡(jiǎn)單的說(shuō),HashSet集合判斷兩個(gè)元素相等的標(biāo)準(zhǔn)是兩個(gè)對(duì)象通過(guò)equals方法比較相等,并且兩個(gè)對(duì)象的hashCode()方法返回值相等
- 注意,如果要把一個(gè)對(duì)象放入HashSet中,重寫(xiě)該對(duì)象對(duì)應(yīng)類的equals方法,也應(yīng)該重寫(xiě)其hashCode()方法。其規(guī)則是如果兩個(gè)對(duì)象通過(guò)equals方法比較返回true時(shí),其hashCode也應(yīng)該相同。另外,對(duì)象中用作
- equals比較標(biāo)準(zhǔn)的屬性,都應(yīng)該用來(lái)計(jì)算hashCode的值。
二、LinkedHashSet
nkedHashSet集合同樣是根據(jù)元素的hashCode值來(lái)決定元素的存儲(chǔ)位置,但是它同時(shí)使用鏈表維護(hù)元素的次序。這樣使得元素看起 來(lái)像是以插入順序保存的,也就是說(shuō),當(dāng)遍歷該集合時(shí)候,LinkedHashSet將會(huì)以元素的添加順序訪問(wèn)集合的元素。
- LinkedHashSet中不能有相同元素,可以有一個(gè)Null元素,元素嚴(yán)格按照放入的順序排列。
- LinkedHashSet如何保證有序和唯一性?
- 底層數(shù)據(jù)結(jié)構(gòu)由哈希表和鏈表組成。
- 鏈表保證了元素的有序即存儲(chǔ)和取出一致,哈希表保證了元素的唯一性。
- 添加、刪除操作時(shí)間復(fù)雜度都是O(1)。
- 非線程安全
三、TreeSet
TreeSet是SortedSet接口的唯一實(shí)現(xiàn)類,TreeSet可以確保集合元素處于排序狀態(tài)。
TreeSet支持兩種排序方式,自然排序 和定制排序,其中自然排序?yàn)槟J(rèn)的排序方式。
向TreeSet中加入的應(yīng)該是同一個(gè)類的對(duì)象。
TreeSet判斷兩個(gè)對(duì)象不相等的方式是兩個(gè)對(duì)象通過(guò)equals方法返回false,或者通過(guò)CompareTo方法比較沒(méi)有返回0
自然排序
自然排序使用要排序元素的CompareTo(Object obj)方法來(lái)比較元素之間大小關(guān)系,然后將元素按照升序排列。
定制排序
自然排序是根據(jù)集合元素的大小,以升序排列,如果要定制排序,應(yīng)該使用Comparator接口,實(shí)現(xiàn) int compare(T o1,T o2)方法
1.TreeSet是中不能有相同元素,不可以有Null元素,根據(jù)元素的自然順序進(jìn)行排序。
2.TreeSet如何保證元素的排序和唯一性?
底層的數(shù)據(jù)結(jié)構(gòu)是紅黑樹(shù)(一種自平衡二叉查找樹(shù))
3.添加、刪除操作時(shí)間復(fù)雜度都是O(log(n))
4.非線程安全
TreeSet排序如下
public class Person3 { private int age; private String name; public Person3(String name, int age){ this.name = name; this.age = age; } @Override public String toString() { return "Person{" + "age=" + age + ", name='" + name + '\'' + '}'; } public static void main(String[] args) { Set<Person3> set = new TreeSet<>(new Comparator<Person3>() { @Override public int compare(Person3 o1, Person3 o2) { if(o1 == null || o2 == null){ return 0; } return o1.age - o2.age; } }); set.add(new Person3("zzh",18)); set.add(new Person3("jj",17)); set.add(new Person3("qq",19)); set.add(new Person3(null,19)); //[Person{age=17, name='jj'}, Person{age=18, name='zzh'}, Person{age=19, name='qq'}] System.out.println(set); }
四.總結(jié)
通過(guò)以上特點(diǎn)可以分析出,三者都保證了元素的唯一性,如果無(wú)排序要求可以選用HashSet;
如果想取出元素的順序和放入元素的順序相同,那么可以選用LinkedHashSet。如果想插入、刪除立即排序或者按照一定規(guī)則排序可以選用TreeSet。
到此這篇關(guān)于Java中HashSet、LinkedHashSet和TreeSet區(qū)別詳解的文章就介紹到這了,更多相關(guān)HashSet、LinkedHashSet和TreeSet內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java LinkedHashSet集合的底層原理和TreeSet集合
- Java中HashMap和HashSet的高效使用技巧分享
- Java中的Set接口實(shí)現(xiàn)類HashSet和LinkedHashSet詳解
- Java集合ArrayList、LinkedList、HashMap、HashSet最大容量
- java的==運(yùn)算符和equals操作詳解
- Java中==和equals()的區(qū)別總結(jié)
- java兩個(gè)integer數(shù)據(jù)判斷相等用==還是equals
- 詳解Java中==和equals()的區(qū)別
- 淺談java字符串比較到底應(yīng)該用==還是equals
- java中的HashSet與 == 和 equals的區(qū)別示例解析
相關(guān)文章
spring集成mybatis實(shí)現(xiàn)mysql數(shù)據(jù)庫(kù)讀寫(xiě)分離
本文通過(guò)實(shí)例代碼給大家介紹了spring集成mybatis實(shí)現(xiàn)mysql數(shù)據(jù)庫(kù)讀寫(xiě)分離,需要的朋友可以參考下2017-08-08springboot 加載 META-INF/spring.factories方式
這篇文章主要介紹了springboot 加載 META-INF/spring.factories方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10MyBatis 多表查詢?nèi)N最常見(jiàn)的寫(xiě)法
這篇文章主要介紹了MyBatis 多表查詢?nèi)N最常見(jiàn)的寫(xiě)法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2025-04-04Mybatis 多對(duì)一查詢的實(shí)現(xiàn)方法
這篇文章主要介紹了Mybatis 多對(duì)一查詢,本文通過(guò)場(chǎng)景分析示例代碼相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02springboot循環(huán)依賴問(wèn)題案例代碼及解決辦法
在 Spring Boot 中,如果兩個(gè)或多個(gè) Bean之間存在循環(huán)依賴(即 Bean A 依賴 Bean B,而 Bean B 又依賴 Bean A),會(huì)導(dǎo)致 Spring 的依賴注入機(jī)制無(wú)法正確處理,從而拋出異常,下面給大家介紹springboot循環(huán)依賴問(wèn)題及其解決辦法,感興趣的朋友一起看看吧2025-04-04java進(jìn)行遠(yuǎn)程部署與調(diào)試及原理詳解
這篇文章主要介紹了java進(jìn)行遠(yuǎn)程部署與調(diào)試及原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12java在linux系統(tǒng)下開(kāi)機(jī)啟動(dòng)無(wú)法使用sudo命令的原因及解決辦法
每次開(kāi)機(jī)自動(dòng)啟動(dòng)的java進(jìn)程,頁(yè)面上的關(guān)機(jī)按鈕都無(wú)法實(shí)現(xiàn)關(guān)機(jī)功能,但是此時(shí)如果以chb賬號(hào)通過(guò)ssh登錄該服務(wù)器,手動(dòng)殺掉tomcat進(jìn)程,然后再重新啟動(dòng)tomcat,頁(yè)面上的關(guān)機(jī)按鈕就有效了2013-08-08springcloud中Ribbon和RestTemplate實(shí)現(xiàn)服務(wù)調(diào)用與負(fù)載均衡
這篇文章主要介紹了Ribbon和RestTemplate實(shí)現(xiàn)服務(wù)調(diào)用與負(fù)載均衡,想了解負(fù)載均衡的同學(xué)可以參考下2021-04-04Spring向頁(yè)面?zhèn)髦岛徒邮茼?yè)面?zhèn)鬟^(guò)來(lái)的參數(shù)詳解
這篇文章主要給大家介紹了關(guān)于Spring向頁(yè)面?zhèn)髦岛徒邮茼?yè)面?zhèn)鬟^(guò)來(lái)的參數(shù)的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-06-06