(1)LinkedHashSet的底層使用什么存儲(chǔ)元素?
寧海網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)建站!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、響應(yīng)式網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)建站于2013年成立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專(zhuān)注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)建站。
(2)LinkedHashSet與HashSet有什么不同?
(3)LinkedHashSet是有序的嗎?
(4)LinkedHashSet支持按元素訪問(wèn)順序排序嗎?
上一節(jié)我們說(shuō)HashSet中的元素是無(wú)序的,那么有沒(méi)有什么辦法保證Set中的元素是有序的呢?
答案是當(dāng)然可以。
我們今天的主角LinkedHashSet就有這個(gè)功能,它是怎么實(shí)現(xiàn)有序的呢?讓我們來(lái)一起學(xué)習(xí)吧。
LinkedHashSet繼承自HashSet,讓我們直接上源碼來(lái)看看它們有什么不同。
package java.util;
// LinkedHashSet繼承自HashSet
public class LinkedHashSet
extends HashSet
implements Set, Cloneable, java.io.Serializable {
private static final long serialVersionUID = -2851667679971038690L;
// 傳入容量和裝載因子
public LinkedHashSet(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor, true);
}
// 只傳入容量, 裝載因子默認(rèn)為0.75
public LinkedHashSet(int initialCapacity) {
super(initialCapacity, .75f, true);
}
// 使用默認(rèn)容量16, 默認(rèn)裝載因子0.75
public LinkedHashSet() {
super(16, .75f, true);
}
// 將集合c中的所有元素添加到LinkedHashSet中
// 好奇怪, 這里計(jì)算容量的方式又變了
// HashSet中使用的是Math.max((int) (c.size()/.75f) + 1, 16)
// 這一點(diǎn)有點(diǎn)不得其解, 是作者偷懶?
public LinkedHashSet(Collection extends E> c) {
super(Math.max(2*c.size(), 11), .75f, true);
addAll(c);
}
// 可分割的迭代器, 主要用于多線程并行迭代處理時(shí)使用
@Override
public Spliterator spliterator() {
return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED);
}
}
完了,結(jié)束了,就這么多,這是全部源碼了,真的。
可以看到,LinkedHashSet中一共提供了5個(gè)方法,其中4個(gè)是構(gòu)造方法,還有一個(gè)是迭代器。
4個(gè)構(gòu)造方法都是調(diào)用父類(lèi)的super(initialCapacity, loadFactor, true);
這個(gè)方法。
這個(gè)方法長(zhǎng)什么樣呢?
還記得我們上一節(jié)說(shuō)過(guò)一個(gè)不是public的構(gòu)造方法嗎?就是它。
// HashSet的構(gòu)造方法
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
如上所示,這個(gè)構(gòu)造方法里面使用了LinkedHashMap來(lái)初始化HashSet中的map。
現(xiàn)在這個(gè)邏輯應(yīng)該很清晰了,LinkedHashSet繼承自HashSet,它的添加、刪除、查詢(xún)等方法都是直接用的HashSet的,唯一的不同就是它使用LinkedHashMap存儲(chǔ)元素。
那么,開(kāi)篇那幾個(gè)問(wèn)題是否能回答了呢?
(1)LinkedHashSet的底層使用LinkedHashMap存儲(chǔ)元素。
(2)LinkedHashSet是有序的,它是按照插入的順序排序的。
通過(guò)上面的學(xué)習(xí),我們知道LinkedHashSet底層使用LinkedHashMap存儲(chǔ)元素,而LinkedHashMap是支持按元素訪問(wèn)順序遍歷元素的,也就是可以用來(lái)實(shí)現(xiàn)LRU的,還記得嗎?傳送門(mén)【死磕 java集合之LinkedHashMap源碼分析】
那么,LinkedHashSet支持按元素訪問(wèn)順序排序嗎?
讓我們一起來(lái)分析下。
首先,LinkedHashSet所有的構(gòu)造方法都是調(diào)用HashSet的同一個(gè)構(gòu)造方法,如下:
// HashSet的構(gòu)造方法
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
然后,通過(guò)調(diào)用LinkedHashMap的構(gòu)造方法初始化map,如下所示:
public LinkedHashMap(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor);
accessOrder = false;
}
可以看到,這里把a(bǔ)ccessOrder寫(xiě)死為false了。
所以,LinkedHashSet是不支持按訪問(wèn)順序?qū)υ嘏判虻?,只能按插入順序排序?/p>
歡迎關(guān)注我的公眾號(hào)“彤哥讀源碼”,查看更多源碼系列文章, 與彤哥一起暢游源碼的海洋。