Java中的 ArrayList、LinkedList、Vector
摘要
极客时间里的Java核心技术系列,第8讲,记录一些笔记。
关键词:线程安全、扩容、fast-fail、modCount、transient、迭代器、适配器。
ArrayList
觉得应该先来说说 ArrayList,再来说Vector。。。 他们很像。。。
- 不是线程安全的。
- 基于动态数组实现的,默认容量为10。
- 存储元素的数组 elementData 用 transient 关键字来修饰,代表默认不能被 序列化。
但是可以用 ArrayList 里提供的 readObject( ) 和 writeObject( ) 方法来序列化 数组里有元素的那部分内容。 - fast-fail机制:
在进行序列化 或者 迭代等操作时,如果 modCount 这个变量改变了,就会抛 ConcurrentModificationException 异常。
modCount (记录结构发生变化的变量):
添加、删除、调整数组大小都会改变这个值。但是改变一个元素的值不算结构发生变化。 - 在需要扩容的时候, 增量为 原来的一半。 最后是调用 Arrays.copyOf( ) 这个方法来进行数组的拷贝。
- 在需要删除元素时, 底层是调用 System.arraycopy( ) 的native方法,时间复杂度为 O(N)。
Vector
和 ArrayList 很像,基于动态数组实现。默认容量为10。
- 但 Vector 是线程安全的,简单粗暴的基于 synchronized 关键字来实现。
要进行 synchronized 同步,所以开销就比较大,很少用了。
替代方案有:- Collections.synchronizedList( ) 方法。
- concurrent 包下的 CopyOnWriteArrayList 类。
不适合
对内存敏感(写时 是再开辟一块内存空间来写)
和
对实时性要求很高(读时 可能写入的数据还未同步)
的场景。
- 在 扩容 时,可以通过 capacityIncrement 这个参数来选择增加的容量。
默认情况下,增量 为原来的1倍。 之后也是调用 Arrays.copyOf( ) 这个方法来拷贝数组。
LinkedList
-
不是线程安全的。
-
基于 双向链表来实现的。
进行 节点 的插入和删除要高效很多,但是 随机访问 就慢了。 -
可以用作栈、队列、双向队列。
存储结构:
Java 中关于 Collection 中的部分继承关系图:
集合中涉及到的设计模式
-
迭代器模式: 提供一种方法顺序访问 聚合对象 的内部元素。
Collection接口 是 继承自 Iterable 接口的。 -
适配器模式: 把一个接口转换成用户需要的 另一个接口。
Arrays.asList( ) 数组类型 转为 List 类型。
#参考链接:
https://blog.csdn.net/chenssy/article/details/38151189
https://wiki.jikexueyuan.com/project/java-enhancement/java-thirtysix.html
https://www.runoob.com/design-pattern/iterator-pattern.html