Java中的Set接口實(shí)現(xiàn)類HashSet和LinkedHashSet詳解
Set接口
java.util.Set接口和java.util.List接口一樣,同樣繼承自Collection接口,它與Collection接口中的方法基本一致,并沒有對Collection接口進(jìn)行功能上的擴(kuò)充,只是比Collection接口更加嚴(yán)格了。
與List接口不同的是,Set接口中元素?zé)o序,并且都會以某種規(guī)則保證存入的元素不出現(xiàn)重復(fù)。
Set集合有多個子類,這里我們介紹其中的java.util.HashSet、java.util.LinkedHashSet這兩個集合。
HashSet集合介紹
java.util.HashSet是Set接口的一個實(shí)現(xiàn)類,它所存儲的元素是不可重復(fù)的,并且元素都是無序的(即存取順序不一致)。java.util.HashSet底層的實(shí)現(xiàn)其實(shí)是一個java.util.HashMap支持.
HashSet是根據(jù)對象的哈希值來確定元素在集合中的存儲位置,因此具有良好的存取和查找性能。保證元素唯一性的方式依賴于:hashCode與equals方法。
public class test { public static void main(String[] args) { HashSet<String> set = new HashSet<>(); set.add("cba"); set.add("cba"); set.add("cbc"); set.add("cbd"); System.out.println(set); } }
代碼輸出:
說明HashSet實(shí)現(xiàn)類是一個無序并且不重復(fù)的類。
HashSet集合存儲數(shù)據(jù)的結(jié)構(gòu)(哈希表)
什么是哈希表呢?
在JDK1.8之前,哈希表底層采用數(shù)組+鏈表實(shí)現(xiàn),即使用鏈表處理沖突,同一hash值的鏈表都存儲在一個鏈表里。但是當(dāng)位于一個桶中的元素較多,即hash值相等的元素較多時,通過key值依次查找的效率較低。而JDK1.8中,哈希表存儲采用數(shù)組+鏈表+紅黑樹實(shí)現(xiàn),當(dāng)鏈表長度超過閾值(8)時,將鏈表轉(zhuǎn)換為紅黑樹,這樣大大減少了查找時間。
簡單的來說,哈希表是由數(shù)組+鏈表+紅黑樹(JDK1.8增加了紅黑樹部分)實(shí)現(xiàn)的,如下圖所示。
看到這張圖就有人要問了,這個是怎么存儲的呢?
為了方便大家的理解我們結(jié)合一個存儲流程圖來說明一下:
總而言之,JDK1.8引入紅黑樹大程度優(yōu)化了HashMap的性能,那么對于我們來講保證HashSet集合元素的唯一,其實(shí)就是根據(jù)對象的hashCode和equals方法來決定的。
如果我們往集合中存放自定義的對象,那么保證其唯一,就必須復(fù)寫hashCode和equals方法建立屬于當(dāng)前對象的比較方式。
LinkedHashSet
我們知道HashSet保證元素唯一,可是元素存放進(jìn)去是沒有順序的,那么我們要保證有序,怎么辦呢?
在HashSet下面有一個子類java.util.LinkedHashSet,它是鏈表和哈希表組合的一個數(shù)據(jù)存儲結(jié)構(gòu)。
public class LinkedHashSetDemo { public static void main(String[] args) { Set<String> set = new LinkedHashSet<String>(); set.add("bbb"); set.add("aaa"); set.add("abc"); set.add("bbc"); Iterator<String> it = set.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } }
結(jié)果:
bbb
aaa
abc
bbc
LinkedHashSet特點(diǎn)就是里面的元素有序,不重復(fù)。
到此這篇關(guān)于Java中的Set接口實(shí)現(xiàn)類HashSet和LinkedHashSet詳解的文章就介紹到這了,更多相關(guān)Set接口實(shí)現(xiàn)類詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java LinkedHashSet集合的底層原理和TreeSet集合
- Java中HashMap和HashSet的高效使用技巧分享
- Java集合ArrayList、LinkedList、HashMap、HashSet最大容量
- Java中HashSet、LinkedHashSet和TreeSet區(qū)別詳解
- java的==運(yùn)算符和equals操作詳解
- Java中==和equals()的區(qū)別總結(jié)
- java兩個integer數(shù)據(jù)判斷相等用==還是equals
- 詳解Java中==和equals()的區(qū)別
- 淺談java字符串比較到底應(yīng)該用==還是equals
- java中的HashSet與 == 和 equals的區(qū)別示例解析
相關(guān)文章
SpringBoot中引入MyBatisPlus的常規(guī)操作
這篇文章主要介紹了SpringBoot中引入MyBatisPlus的常規(guī)操作,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Springboot 整合 Dubbo/ZooKeeper 實(shí)現(xiàn) SOA 案例解析
這篇文章主要介紹了Springboot 整合 Dubbo/ZooKeeper 詳解 SOA 案例,需要的朋友可以參考下2017-11-11