From c1fae59120385ab2833bdc87dad4b0cba70a133f Mon Sep 17 00:00:00 2001 From: Omooo <869759698@qq.com> Date: Tue, 2 Jun 2020 17:40:36 +0800 Subject: [PATCH] =?UTF-8?q?Update=20=E9=9B=86=E5=90=88=E6=BA=90=E7=A0=81.m?= =?UTF-8?q?d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- blogs/Java/口水话/集合源码.md | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/blogs/Java/口水话/集合源码.md b/blogs/Java/口水话/集合源码.md index abde592..1beccde 100644 --- a/blogs/Java/口水话/集合源码.md +++ b/blogs/Java/口水话/集合源码.md @@ -9,6 +9,12 @@ 3. LinkedList 4. HashMap 5. Hashtable +6. TreeMap +7. LinkedHashMap +8. HashSet +9. TreeSet +10. CopyOnWriteArrayList +11. ConcurrentHashMap #### ArrayList @@ -58,3 +64,29 @@ HashMap 非线程安全,如果需要满足线程安全,可以用 Collections Hashtable 在扩容时,是 x2 + 1 的。 +#### TreeMap + +TreeMap 底层的数据结构就是红黑树,和 HashMap 的红黑树结构一样。不同的是,TreeMap 通过 compare 来比较 key 的大小,然后利用红黑树左小右大的特性,为每个 key 找到自己的位置,维护了 key 的大小关系,适用于 key 需要排序的场景。 + +因为底层使用的是红黑树的结构,所以它的 put/remove/get 等方法实际复杂度都是 log(n) 的。 + +#### LinkedHashMap + +HashMap 是无序的,TreeMap 可以按照 key 进行排序,那有没有 Map 是可以维护插入顺序的呢?这就是 LinkedHashMap。 + +LinkedHashMap 本身是继承 HashMap 的,所以它拥有 HashMap 的所有特性,在此基础上还提供了两大特性,第一个是按照插入顺序访问,第二个呢是实现了最近最少使用策略,这个需要在构造方法中传一个 accessOrder = true,默认是 false 也就是按照插入顺序访问。 + +在我们调用 put/remove 方法时,其实是调用的 HashMap 的 put/remove 方法,而重写了 get 方法实现了以上特性。那么它是如何基于 HashMap 实现了以上特性的呢?其实是通过重写 HashMap 里面的三个方法,这个三个方法是每当 HashMap 调用 put/get/remove 时都会调用的,只不过在 HashMap 中是一个空实现,而在 LinkedHashMap 中它被用来记录插入顺序,其实也就是扩展 HashMap 的 Node 使其具备链表结构,也就是每个数组元素增加 befor 和 after 属性。 + +但是呢,LinkedHashMap 只提供了单向访问,即按照插入的顺序从头到尾进行访问,不能像 LinkedList 那样可以双向访问。 + +在使用 LRU 策略时,可以覆写删除策略的方法 removeEldestEntry 方法,比如可以指定当节点数大于 10 就开始头结点(size() > 10)等等。 + +#### HashSet + +HashSet 的源码还是很少的,它保证了每个元素是不会重复的。在它的构造方法中,其实是 new HashMap 来做的,一般我们只使用它的 add 和 contains 方法,其实都是调用 HashMap 来实现的。 + +这个类也没说可说的了,代码就那几十行。 + +#### TreeSet +