开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第31天,点击查看活动详情
List 集合:
ArrayList() 是有序的动态数组列表,只能装载包装类(Integer、String、Double、Object等),允许为null和重复元素,特点:查询快、增加、删除慢
Arrraylist扩容机制
-
使用
ArrayList()构造函数时,会构造一个长度为0的数组,是一个Object数组. -
ArrayList(int initalCapacity)会使用指定容量的数组 -
public ArrayList(Collection <? extends E> c)会使用集合c的大小作为数组容量 -
add(Object o)首次扩容为10,再次扩容为上次容量的1.5倍(0.5 采用的是右移运算)且只针对初始容量为0的数组,每次扩容1.5倍的大小依次为:[0、10、15、22、33、49、73、109、163、244、366、549、823、1234、1851、2776] -
addAll(Collection c)没有元素时,扩容为Math.max(10,实际元素的个数),有元素时为Math.max(原始容量的1.5倍,实际元素的个数)
fail-fast与fail-safe
-
ArrayList是fail-fast的典型代表,遍历的同时不能修改,会报异常,尽快失败 -
CopyOnWriteArrayList是fail-safe的典型代表,遍历时可以修改,原理是读写分离
LinkedList 与ArrayList区别:
ArrayList底层基于动态数组实现的,LinkedList底层基于双向链表实现的- 访问:对于随机访问,(get/set访问)
ArrayList实现了RandomAccess接口,可以直接定位到数组对应下标节点,而LinkedList需要从头节点或者尾节点开始遍历直到找到目标元素,所以:Arraylist访问速率>LinkedList访问速率 - 插入和删除:
- 随机插入和删除:
ArrayList需要移动目标后面的节点(使用System.arrarcopy移动节点),而LinkedList只需要修改目标节点的next或者prev,所以:ArrayList随机插入删除效率**<**LinkedList随机插入和删除效率 - 顺序插入和删除:
ArrayList不需要移动节点,ArrayLists顺序插入效率>LinkedList顺序插入和删除,大多数情况使用ArrayList,因为大多数情况都是顺序插入 - 头尾插入删除:
ArrayList尾部插入、删除性能高,但是部分插入需要移动元素,性能低。LinkedList头部、尾部插入删除性能高
- 随机插入和删除:
- 线程安全:LinkedList和ArrayList线程均不安全