ArrayList

作者: 淘技术 | 来源:发表于2020-03-31 20:44 被阅读0次

基本实现
1)底层实现为数组
2)实现了randomAccess接口,实现快速随机访问(通过index访问)
3)实现了Serializable接口,便于序列化/反序列化(write/read inputStream)
4)实现了Cloneable,便于克隆(默认浅拷贝)
5)继承AbstractList,AbstractList定义了基本方法,但是没有任何实现,要求子类自己完善方法,否则报错
6)实现了list,其中也定义了一些集合接口
基础常量
1)默认容器大小10
2)两个空数组对象,为什么定义两个呢?因为通过这两个区分空数组是否由用户定义,来判断第一次add时初始化容器大小
3)size为当前集合已有数据集大小
4)最大容量Integer,MAX - 8
构造函数
1)无参构造方法,默认初始化空数组
2)带初始容器大小构造方法
3)带集合参数构造方法
常用方法
1)add()
添加元素,会校验容器大小,如果大小不够,默认1.5倍扩容
2)remove()
删除元素,现将数组迁移,最后一个数据设置为null,使用的system实现重新copy
3)set()
直接根据index将对应数据更改
4)get()
根据index获取数据
5)toString()
获取迭代器,使用StringBuilder对象进行拼接
6)iterator()
迭代器,内部类Itr()
成员变量
1.光标cursor
2.记录-1
3.实际修改次数赋值预期修改次数
hasNext()
1.判断光标与size
next()
1.校验修改次数是否等于预期修改次数
2.然后根据当前cursor作为index取值
特殊情况:当要删除的元素是倒数第二个时就不会产生并发修改异常
remove()
1.迭代器自带删除方法,不会导致并发修改异常
7)clear()
遍历for循环,index所有值置为null,size = 0
8)indexOf()
遍历for循环,判断
9)isEmpty()
size == 0
面试题
问:ArrayList扩容机制?
答:如果是通过无参构造方法创建的集合,第一次会进行容量为10的扩容,之后如果大小不够会进行1.5倍扩容。其他也是

问:ArrayList频繁扩容导致性能急剧下降,如何解决?
答:尽可能的初始化好容量,或者在代码执行过程中,手动扩容,减少扩容次数

问:ArrayList插入和删除元素一定比LinkedList慢吗?
答:不一定。ArrayList删除动作:根据索引直接取出元素,system.arraycopy(),复制,最后一位设置null。
LinkedList删除动作:根据index大小,分为从前往后和从后往前查询,也是需要遍历。删除时还需要获取上一个/下一个/当前节点。对节点的上下进行链接

问:ArrayList是线程安全的吗?
答:不是同步的,非线程安全。可以对对应的代码块加锁之类的操作。Vertor是线程安全的,同步说明了效率低,开销大,除非线程安全使用,其余情况使用ArrayList(add()方法加了同步锁)。或者通过Collections.synchronizedList(),创建一个安全的线程。

问:什么情况下需要ArrayList安全
答:ArrayList作为成员变量,多线程使用同一集合时

问:如何复制某个ArrayList到另一个ArrayList
答:clone方法。构造函数。addAll方法

问:已知成员变量集合存储N多用户名称,在多线程的环境下,使用迭代器在读取集合的同事如何保证还可以正常的写入数据到集合?
答:使用CopyOnWriteArrayList,读写分离集合

问:ArrayList和LinkedList区别?
答:ArrayList
1)基于动态数组的数据结构
2)对于随机访问的get/set,ArrayList要由于LinkedList
3)对于随机的操作,add和remove,ArrayList不一定比linkedList慢(底层为数组,不一定每次都创建新的数组)
LinkedList
1)基于链表的数据结构
2)对于顺序操作,LinkedList不一定比ArrayList慢
3)对于随机操作,效率明显较低

相关文章

网友评论

      本文标题:ArrayList

      本文链接:https://www.haomeiwen.com/subject/vpiguhtx.html