深入理解ArrayList(四)

简介: 深入理解ArrayList(四)

通过第三讲的代码改进深入理解ArrayList(三),现在我们的代码能够实现底层数组的自动扩容,能够适应任意数量的元素插入,而且能够添加各种类型的元素,基本已经能够满足日常的开发需求。还有什么地方可以改进的呢?


首先来回顾一下上一讲的思路,在上一讲最突出的贡献就是在添加元素之前,进行了数组容量的判断,如果当前数组容量足够则直接添加,否则申请新的数组,将原数组的内容全部复制到新数组,然后再进行元素添加。


其核心的扩容算法如下:

87b1624e59122bbdb271145e34e6ea89.jpg

size表示当前已经存放的元素的个数,由于插入的是一个元素,因此需要的最小容量是size+1,接着判断最小容量是否超出了数组的大小,超出则申请size+1的数组。


上面红色标记字体就是需要重点关注的地方,从上面描述的算法可以得出,当超出数组默认的大小后,每次添加一个新的元素后,都会申请新的数组,进行数组复制操作。为什么会出现这样的情况呢?


原因在于每次申请的新的数组容量都是size+1即新申请的数组容量都只够当前元素的添加,也就是每次申请的数组空间都只能满足当前需求,而没有考虑到今后是否还需要继续添加元素。


所以,minCapacity只是当前需要的最小容量,但是并不代表这就是申请的新的容量。那么多少才是合适的呢?


可以选择一个简单的算法,那就是每次申请原数组容量的1.5倍,

99a93170ac1e16054a7d9988dafbf9ef.png


这个算法虽然比较简单,但是需要注意:

整数的加法是有可能出现溢出的,如minCapacity = size+1 以及上面的newCapacity,这两个变量都是有可能出现溢出的,因此在使用的时候需要进行判断。这也是平时我们在设计算法中如果使用到加法运算应该慎重考虑的地方。


总结


本文在上一讲的基础上针对数组扩容时每次申请size+1的容量导致超过初始默认容量后就需要一直不断的进行扩容操作,提出一种新的数组扩容算法,使其效率更高。

目录
相关文章
|
1月前
|
存储 Java
ArrayList
ArrayList是线程不安全的,底层使用 Object[]存储数据,可以存储任何类型的对象,包括 null 值,相当于动态数组。与 Java 中的数组相比,它的容量能动态增长。 核心属性: private static final int DEFAULT_CAPACITY = 10;//默认容量 transient Object[] 存储元素的集合 private int size; 元素个数 构造方法: public ArrayList() ; public ArrayList(int initialCapacity) ; public ArrayList(Collection<?
|
2月前
|
安全 Java API
ArrayList 全面详解
关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。本文详细解析了Java集合框架中的ArrayList,包括其定义、特点、成员变量、构造函数、API、主要方法和扩容机制等。欢迎留言交流。
|
4月前
|
存储
ArrayList的使用
ArrayList的使用
26 3
|
安全 Java
你对ArrayList了解多少?
你对ArrayList了解多少?
46 0
|
存储 安全 Java
ArrayList引发的一系列问题
ArrayList引发的一系列问题
105 0
ArrayList引发的一系列问题
|
Java 测试技术 索引
深入理解ArrayList(三)
深入理解ArrayList(三)
74 0
|
存储 设计模式 算法
ArrayList和LinkedList
介绍ArrayList和LinkedList
详解ArrayList
1.数据结构 底层使用Object类型的数组实现,线程不安全,添加元素时如果内存已满则会开辟新空间,将原数组copy过去。
99 0
深入理解ArrayList(一)
深入理解ArrayList(一)
75 0