ArrayList Iterator LinkedList面试考点(源码分析)

ArrayList:

扩容规则:

  1. ArrayList() 空参构造会使用长度为零的数组

  2. ArrayList(int initialCapacity) 会使用指定容量的数组

  3. public ArrayList(Collection<? extends E> c) 会使用 c 的大小作为数组容量

  4. add(Object o) 首次扩容为 10,再次扩容为上次容量的 1.5 倍

  5. addAll(Collection c) 没有元素时,扩容为 Math.max(10, 实际元素个数),有元素时为 Math.max(原容量 1.5 倍, 实际元素个数)

Iterator:

fail-fast和fail-safe:

  • ArrayList 是 fail-fast 的典型代表,线程不安全,遍历的同时不能修改,尽快失败

    遍历时无法修改:因为底层在调用迭代器是首先记录了ArrayList的修改次数,并且将这个次数保存到迭代器成员属性中,在每次迭代遍历时首先会判断数组的修改次数和刚传入时的修改次数是否一致,不一致则会抛出异常。例如:使用空参构造创建了一个ArrayList对象,并用add方法向其中加入了三个元素,此时原ArrayList修改次数(modCount)为3,迭代器会记录当前这个修改次数,保存在expectedModCount中,如果此时对原List修改,会改变modCount的值,使其与expectedModCount的值不相等,在检查时抛出异常。
  • CopyOnWriteArrayList 是 fail-safe 的典型代表,线程安全,遍历的同时可以修改,原理是读写分离

    遍历时可以修改:在调用迭代器遍历时,迭代器会先将此时的元素保存到其内部的一个final数组中,此后的迭代过程全是相对于这个内部的final数组进行的,也就是说如果在迭代过程中对原List进行修改,迭代会继续进行,不过对于新修改的部分迭代器时遍历不出来的,只能迭代出修改之前的List。

LinkedList:

实现:

底层依靠双向链表来实现的。一般使用ArrayList即可。

ArrayList和LinkedList比较:

ArrayListLinkedList
内存分配基于数组,需要连续内存 基于双向链表,无需连续内存
随机访问快(通过索引)慢(遍历链表)
插入数据尾部插入、删除性能可以,其它部分插入、删除都会移动数据,因此性能会低

头尾插入、删除性能高,中间性能低

cpu局部性有效利用占用内存多

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值