Update 集合源码.md

master
Omooo 5 years ago
parent 240c2765f3
commit c1fae59120
  1. 32
      blogs/Java/口水话/集合源码.md

@ -9,6 +9,12 @@
3. LinkedList 3. LinkedList
4. HashMap 4. HashMap
5. Hashtable 5. Hashtable
6. TreeMap
7. LinkedHashMap
8. HashSet
9. TreeSet
10. CopyOnWriteArrayList
11. ConcurrentHashMap
#### ArrayList #### ArrayList
@ -58,3 +64,29 @@ HashMap 非线程安全,如果需要满足线程安全,可以用 Collections
Hashtable 在扩容时,是 x2 + 1 的。 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

Loading…
Cancel
Save