简单了解ArrayList和LinkedList

本文对比了ArrayList和LinkedList在底层数据结构、增删改查效率、线程安全性以及序列化需求上的差异,特别强调了ArrayList的扩容策略和LinkedList的插入删除操作。

List

ArrayList和LinkedList的区别

底层数据结构的不同,ArrayList是数组,LinkedList是双向链表

两者增删改查的效率各不相同,ArrayList可以根据索引更快的查找,而对于LinkedList来说,增加和删除元素的效率更好

两者都是线程不安全的,对于ArrayList来说,Vector就是其线程安全版本的实现,但是两者的一些实现细节还是略有区别,比如说扩容机制,ArrayList是扩容到原容量的1.5倍,而Vector是扩容到原容量的2倍

ArrayList
底层是数组,transient是一个关键字,只能用来修饰成员变量,表示这个成员变量不能被序列化,那什么时候需要序列化呢?比如一些网络传输的时候我们会把数据序列化传输,这样传输的数据量小

image-20240115100728681

add()

在添加元素之前会先判断是否需要扩容,如果需要扩容,我们会调用grow()函数进行扩容,也可以看到这里有个懒加载的机制,在第一次添加元素的时候ArrayList才会初始化底层的数组(默认容量是10),如果不需要扩容,我们可以直接插入元素

image-20240115100830425

grow()

首先对于数组来说,数组是没有扩容机制的,ArrayList底层实现扩容的方式就是创建一个更大容量的新数组,ArrayList底层的扩容机制默认扩容到原容量的1.5倍,如果初始为0,那么扩容到1;如果初始为1,那么扩容到2,再通过Arrays.copyof() 将旧的数组的每个元素copy过去

image-20240115101353211

remove()

ArrayList在删除元素之前会先检查位置是否合法,然后再删除,需要调用native方法移动数组元素

image-20240115102204254

get()

根据下标直接返回元素

image-20240115103317507

LinkedList
底层是双向链表,有一个头节点以及一个尾节点

image-20240115102442807

每个节点的结构 

image-20240115102719636

add()

可以在else分支看到LinkedList使用的是尾插法插入新的节点

image-20240115102842291

remove()

拿到待删除节点的前后节点,进行双向链表那样的删除,也就是将该节点的前驱节点和后继节点连接起来

image-20240115102922252

get(int index)

LinkedList底层会用二分法先优化一下,索引位置和链表长度的一半先比对一下,判断从左半边遍历还是右半边遍历,当然还有getFirst()以及getLast()方法快速的获取头尾节点

image-20240115103138904

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值