Java 代码中常见的 List 实现类有 ArrayList、LinkedList、Vector 等
ArrayList 和 Vector 底层都基于数组实现,区别在于 Vector 方法通过 Synchronized 修饰,保证线程安全、并且 ArrayList 扩容后长度为原来 1.5 倍,而 Vector 变为原来两倍
LinkedList 底层基于双向链表实现(它还实现 Deque 接口),节点在内存地址上不连续
由于实现方式的不同,ArrayList 和 LinkedList 有以下区别:
- 对于随机访问,比如某个下标的节点,ArrayList 节点在内存上连续,只需找到首地址依次遍历即可,而 LinkedList 需要从首节点开始,根据 next 指针,依次查找。总得来说,ArrayList 效率更高
- 对于随机添加、删除元素,ArrayList 需要修改被操作节点及其以后所有节点,而 LinkedList 只需处理对应节点的 prev、next 指针指向即可,LinkedList 效率更高
- 对于顺序添加、删除,ArrayList 无须处理其它节点,效率更高
- 内存占用上,ArrayList 根据扩容因子在数组后会额外占用一部分内存,而 LinkedList 每个节点内存维护指针等数据
- 两者线程都不安全
List 实现类中,除了 Vector 线程安全外,还有 CopyOnWriteArraylist:
CopyOnWriteArraylist 基于数组实现,读操作不加锁,写操作时使用 ReentrantLock 锁,比如 add() 操作,首先加锁,创建新数组,新数组长度为原数组长度 + 1,原数组数据复制到新数据,改变指针指向新数据,解锁。
就我个人感觉,CopyOnWriteArraylist 效率较差,因为它需要频繁创建新数组,改变指针指向,不过在读多写少的场景可以尝试使用