|
|
@ -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 |
|
|
|
|
|
|
|
|
|
|
|