ArrayList
本质还是数组,默认容量是10
主要的核心在于扩容
数组的扩容无非就是新建一个数组,然后进行拷贝。如果考虑性能的话平时尽量不要让这个容器进行频繁拷贝,提前分配好容量。
Vector
官方已经不推荐使用了,没使用过
实现原理跟ArrayList差不多,差别主要是不是线程安全的
Queue和Deque
队列的几个接口区别**
LinkedList
不需要扩容,就是正常的链表操作
这里继承了队列的功能
队列的功能主要通过联调的头结点和尾结点来实现
这里可以看下遍历remove可能会遇到的问题,所以都是用Iteator来遍历操作链表
HashMap
节点结构
这个的原理没看懂
hash函数
这个hash的选择更多是数学经验,只要足够离散就好,可以参考《hash的原理》
数据结构
hash冲突使用链表法,链表长度超过8则会转换成红黑树
虽然红黑树的引入自然在查询上有性能上的提升,那为什么是8呢?经验值?
hash冲突是会发生,但链表超过8的概率这么低,这种优化如果不是真的有洁癖或者闲的发慌我是不做的….
同样loadFactor为什么是0.75更多也是数学统计上的经验值(泊松分布?)
put的流程
扩容过程
数组位置的扩容举例
HashTable
没有用过,不推荐使用
这里还继承了字典类
总体和JDK 7的HashMap实现方式差距不大
这里用了sychronized进行同步,如果追求性能使用_ConcurrentHashMap会更好,锁粒度上有所差距,但是在并发竞争不激烈的情况下应该差距应该不大,毕竟_sychronized在JDK 8中已经经过了优化。
TreeMap
LinkedHashMap
LinkedHashMap 在 HashMap 的基础上增加了顺序:分别为「插入顺序」和「访问顺序」。即遍历 LinkedHashMap 时,可以保持与插入顺序一致的顺序;或者与访问顺序一致的顺序。则意味着可以使用它来做类似缓存的工作。
节点结构上继承了HashMap的Node,增加了before和after来形成链表
put流程
直接使用父类HashMap的put方法,然后重写了newNode、afterNodeAccess、afterNodeInsertion等方法
有序就是在这里实现的
这里就是很明显的淘汰策略了,但方法是空的,这样我们可以使用这个方法来自定义淘汰策略
这个在get的时候进行了顺序调整?有点奇葩啊
实现一个LRU
PriorityQueue
就是两个反向操作
堆化是有集合初始化进行的,可以看到是从中间位置开始