摘要:就有這個功能,它是怎么實現有序的呢源碼分析繼承自,讓我們直接上源碼來看看它們有什么不同。是有序的,它是按照插入的順序排序的。所以,是不支持按訪問順序對元素排序的,只能按插入順序排序。
介紹
上一節我們說HashSet中的元素是無序的,那么有沒有什么辦法保證Set中的元素是有序的呢?
答案是當然可以。 LinkedHashSet就有這個功能,它是怎么實現有序的呢?
源碼分析LinkedHashSet繼承自HashSet,讓我們直接上源碼來看看它們有什么不同。
package java.util; // LinkedHashSet繼承自HashSet public class LinkedHashSetextends HashSet implements Set , Cloneable, java.io.Serializable { private static final long serialVersionUID = -2851667679971038690L; // 傳入容量和裝載因子 public LinkedHashSet(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor, true); } // 只傳入容量, 裝載因子默認為0.75 public LinkedHashSet(int initialCapacity) { super(initialCapacity, .75f, true); } // 使用默認容量16, 默認裝載因子0.75 public LinkedHashSet() { super(16, .75f, true); } // 將集合c中的所有元素添加到LinkedHashSet中 // 好奇怪, 這里計算容量的方式又變了 // HashSet中使用的是Math.max((int) (c.size()/.75f) + 1, 16) // 這一點有點不得其解, 是作者偷懶? public LinkedHashSet(Collection extends E> c) { super(Math.max(2*c.size(), 11), .75f, true); addAll(c); } // 可分割的迭代器, 主要用于多線程并行迭代處理時使用 @Override public Spliterator spliterator() { return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED); } }
完了,這是全部源碼了。
可以看到,LinkedHashSet中一共提供了5個方法,其中4個是構造方法,還有一個是迭代器。
4個構造方法都是調用父類的super(initialCapacity, loadFactor, true);這個方法。
這個方法就是我們上一節說過,HashSet的一個不是public的構造方法。
// HashSet的構造方法 HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); }
如上所示,這個構造方法里面使用了LinkedHashMap來初始化HashSet中的map。
現在這個邏輯應該很清晰了,LinkedHashSet繼承自HashSet,它的添加、刪除、查詢等方法都是直接用的HashSet的,唯一的不同就是它使用LinkedHashMap存儲元素。
總結(1)LinkedHashSet的底層使用LinkedHashMap存儲元素。
(2)LinkedHashSet是有序的,它是按照插入的順序排序的。
思考通過上面的學習,我們知道LinkedHashSet底層使用LinkedHashMap存儲元素,而LinkedHashMap是支持按元素訪問順序遍歷元素的,也就是可以用來實現LRU的。
那么,LinkedHashSet支持按元素訪問順序排序嗎?
讓我們一起來分析下。
首先,LinkedHashSet所有的構造方法都是調用HashSet的同一個構造方法,如下:
// HashSet的構造方法 HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); } ## 然后,通過調用LinkedHashMap的構造方法初始化map,如下所示: public LinkedHashMap(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); accessOrder = false; }
可以看到,這里把accessOrder寫死為false了。
所以,LinkedHashSet是不支持按訪問順序對元素排序的,只能按插入順序排序。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/76233.html
摘要:介紹底層是通過來實現的,它是一個有序的線程安全的集合。源碼分析它的源碼比較簡單,跟通過實現的基本是一致,只是多了一些取最近的元素的方法。 介紹 ConcurrentSkipListSet底層是通過ConcurrentNavigableMap來實現的,它是一個有序的線程安全的集合。 源碼分析 它的源碼比較簡單,跟通過Map實現的Set基本是一致,只是多了一些取最近的元素的方法。 // ...
摘要:下面總結一下集合常用的三個子類吧無序,允許為,底層是散列表紅黑樹,非線程同步有序,不允許為,底層是紅黑樹非線程同步迭代有序,允許為,底層是雙向鏈表,非線程同步從結論而言我們就可以根據自己的實際情況來使用了。 前言 聲明,本文用的是jdk1.8 前面章節回顧: Collection總覽 List集合就這么簡單【源碼剖析】 Map集合、散列表、紅黑樹介紹 HashMap就是這么簡單【源碼...
摘要:設置應用上線文初始化器的作用是什么源碼如下。來看下方法源碼,其實就是初始化一個應用上下文初始化器實例的集合。設置監聽器和設置初始化器調用的方法是一樣的,只是傳入的類型不一樣,設置監聽器的接口類型為,對應的文件配置內容請見下方。 Spring Boot 的應用教程我們已經分享過很多了,今天來通過源碼來分析下它的啟動過程,探究下 Spring Boot 為什么這么簡便的奧秘。 本篇基于 S...
摘要:當復制集合中的所有元素來創建新的集合時,要求集合中的所有元素必須是同一個枚舉類的枚舉值各實現類的性能分析的性能總比好,特別是最常用的添加查詢元素等操作。因為需要額外的紅黑樹算法來維護集合元素的次序。在創建時進行,以防對集合的意外非同步訪問 HashSet 大多時候使用Set集合時就是使用HashSet實現類。HashSet按Hash算法來存儲集合中的元素,因此具有很好的存取和查找性能 ...
閱讀 2701·2023-04-25 19:13
閱讀 4034·2021-09-22 15:34
閱讀 3059·2019-08-30 14:23
閱讀 1467·2019-08-29 17:17
閱讀 1608·2019-08-29 16:05
閱讀 1542·2019-08-29 13:26
閱讀 1221·2019-08-29 13:19
閱讀 558·2019-08-29 13:16