diff --git a/blogs/Java/口水话/集合源码.md b/blogs/Java/口水话/集合源码.md new file mode 100644 index 0000000..b63ea38 --- /dev/null +++ b/blogs/Java/口水话/集合源码.md @@ -0,0 +1,26 @@ +--- +集合源码口水话 +--- + +目录 + +1. ArrayList +2. Vector +3. LinkedList + +#### ArrayList + +ArrayList 实现了 List 接口,RandomAccess 接口,可以插入空数据以及支持随机访问。它相当于一个动态数组,初始化时是一个空数组,在第一次 add 时设置初始容量为 10,每次扩容都增加到原来的 1.5 倍。简单的 add 就是在 elementData 数组末尾添加一个数据,size++;指定 index 添加数据,就需要拷贝 index 后面的数据后移一位。在删除的时,如果是删除 null,就遍历数组找到第一个 null 值删除,否则就遍历比较 equals 删除指定 index 的数据,其实也就是拷贝 index 后面的数据前移一位。删除数据时,最好使用迭代器来做,避免 CurrentModifyException,它并不只是在并发时才会抛出的,单线程也可能抛出,其实内部是比较 expectedModCount 和 modCount 是否相等来判断的。ArrayList 的性能损耗就来源于数组拷贝,在适当情况下,可以初始化时指定容量大小,避免不必要的扩容操作。其实呢,ArrayList 还有一个缺点,就是不能自动缩容,但是我们可以手动调用 trimToSize 来缩容至当前 size 大小。 + +还有一点是 elementData 是用 transient 修饰的,也就是拒绝数据被自动序列化,因为 ArrayList 并不是所有位置都有数据,所以没必要全部序列化,应该只序列化有数据的部分,所以它重写了 writeObject/readObjet 方法。 + +#### Vector + +Vector 感觉是一个被人抛弃的类,它在初始化时直接设置了数组初始容量为 10,在它的 get/add 等方法都加了 synchronized,完全可以看成是一个加锁的 ArrayList。 + +不同的是,它在扩容时默认是直接加倍的,当然这个是可以控制的,在构造方法中可以传一个增长数,这个数是需要大于 1 的,不然就按 1 处理。比如是 0.75,每次扩容就加 1,是 5 呢每次扩容就加 5。 + +当然,想让 ArrayList 变成线程安全的,还可以使用 Collections.synchronizedList 来做,或者呢,使用 CopyOnWriteArrayList。 + +#### LinkedList +