List学习笔记

85 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第31天,点击查看活动详情

Snipaste_2022-12-26_20-02-27.jpg

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-fastfail-safe

  • ArrayListfail-fast的典型代表,遍历的同时不能修改,会报异常,尽快失败

  • CopyOnWriteArrayListfail-safe的典型代表,遍历时可以修改,原理是读写分离

LinkedListArrayList区别:

  • 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线程均不安全