List 可以替代数组吗?

Java中Array、List的区别

Array—是基于索引(index)的数据结构,它使⽤索引在数组中搜索和读取数据是很快的。Array获取数据的时间复杂度是O(1),但是要删除数据却是开销很⼤的,因为这需要重排数组中的所有数据。

List—是⼀个有序的集合,可以包含重复的元素,提供了按索引访问的⽅式,它实现了Collection接口

List有两个重要的实现类:ArrayList和LinkedList

ArrayList:可以看作是能够⾃动增长容量的数组,利⽤ArrayList的toArray返回⼀个数组;Arrays.asList返回⼀个列表

ArrayList 和 LinkedList

  1. 数据结构: ArrayList底层使用Object[] elementData储存,默认长度为10;LinkedList:底层使用双向链表存储。

2、线程安全: ArrayList 和 LinkedList 都不考虑线程同步,不保证线程安全;

3、底层实现: 在底层实现上,ArrayList 是基于动态数组的,而 LinkedList 是基于双向链表的。事实上,它们很多特性的区别都是因为底层实现不同引起的。比如说:

在遍历速度上: 数组是一块连续内存空间,基于局部性原理能够更好地命中 CPU 缓存行,而链表是离散的内存空间对缓存行不友好;

在访问速度上: 数组是一块连续内存空间,支持 O(1) 时间复杂度随机访问,而链表需要 O(n) 时间复杂度查找元素;

在添加和删除操作上: 如果是在数组的末尾操作只需要 O(1) 时间复杂度,但在数组中间操作需要搬运元素,所以需要 O(n)时间复杂度,而链表的删除操作本身只是修改引用指向,只需要 O(1) 时间复杂度(如果考虑查询被删除节点的时间,复杂度分析上依然是 O(n),在工程分析上还是比数组快);

额外内存消耗上: ArrayList 在数组的尾部增加了闲置位置,而 LinkedList 在节点上增加了前驱和后继指针。

源码参考链接 https://cloud.tencent.com/developer/article/2197859

ArrayList 这么好用,可以完全替代数组吗?

大多数场景可以,但不能完全替代。

ArrayList 是基于 Object 数组封装的动态数组,我们不需要关心底层数组的数据搬运和扩容等逻辑,因此在大多数业务开发场景中,除非是为了最求极致的性能,否则直接使用 ArrayList 代替数组是更好的选择。

那么,ArrayList 有哪些地方上比数组差呢?

举例 1 - ArrayList 等容器类不支持 int 等基本数据类型,所以必然存在装箱拆箱操作;

举例 2 - ArrayList 默认的扩容逻辑是会扩大到原容量的 1.5 倍,在大数据量的场景中,这样的扩容逻辑是否多余,需要打上问题;

举例 3 - ArrayList 的灵活性不够。ArrayList 不允许底层数据有空洞,所有的有效数据都会 “压缩” 到底层数组的首部。因此,当需要基于数组二次开发容器时,ArrayList 并不是一个好选择。

例如,使用 ArrayList 开发栈的结构或许合适,可以在数组的尾部操作数据。但使用 ArrayList 开发队列就不合适,因为在数组的首部入队或出队需要搬运数据;

而数组没有这些约束,我们可以将数组设计为 “环形数组”,就可以避免入队和出队时搬运数据。例如 Java 的 ArrayBlockingQueue 和 ArrayDeque[2] 就是基于数组的队列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值