IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Java8中ArrayList的扩容机制 -> 正文阅读

[游戏开发]Java8中ArrayList的扩容机制

Java8中ArrayList的扩容机制

准备

首先要清楚ArrayList的容量的概念

The array buffer into which the elements of the ArrayList are stored. The capacity of the ArrayList is the length of this array buffer. Any empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA will be expanded to DEFAULT_CAPACITY when the first element is added

这是jdk8源码中对其elementData属性给出的doc解释,意思就是说这个elementData是存储 ArrayList 元素的数组缓冲区。 ArrayList 的容量就是这个数组缓冲区的长度。这里注意ArrayList的容量并不是size属性所对应的值。

The size of the ArrayList (the number of elements it contains).

这是官方对size属性给出的解释,size代表的是ArrayList中包含的元素的个数,从后面的例子中就可以看出差别

先看结论

  1. 当使用add方法添加元素时,list扩容后的大小是上一次的大小的1.5倍(当然这里的扩容指的是经过第一次扩容后容量为10之后的再发生的扩容行为)。
  2. 当使用addAll方法添加元素时,list会进行一次性扩容,不会因为扩容后容量不够而再次扩容,最后一个容量为16的就是一个例子,他不会扩容到15然后再扩容到15 + 15>>1 = 22,而是一次到位,也就是说,使用addAll方法,没有元素时,扩容为 Math.max(10, 实际元素个数),有元素时为 Math.max(原容量的1.5 倍, 实际元素个数)

使用add(E e) 方法添加

public static void main(String[] args) {
    ArrayList<Integer> list4 = new ArrayList<>();
    for (int i = 1; i <= 11; i++) {
        list4.add(i);
        System.out.println("第"+i+"次添加后list4的容量:"+length(list4));
    }

}

/**
 * 使用反射获取其elementData属性的长度即ArrayList的容量
 * @param list
 * @return
 */
public static int length(ArrayList<Integer> list) {
    try {
        Field field = ArrayList.class.getDeclaredField("elementData");
        field.setAccessible(true);
        Object[] elementData = (Object[]) field.get(list);
        return elementData.length;
    } catch (Exception e) {
        e.printStackTrace();
        return 0;
    }
}

当list第一次调用add要向其中添加一个数字0的时候,ArrayList底层会先确保在当前的size+1的情况下内部容量是否够用,够用就放进去,不够就扩容。

在这里插入图片描述

在这里插入图片描述第一次扩容因为elementData为一个长度为0的空数组,下一步会

拿着DEFAULT_CAPACITY(10)和当前size+1中的较大者去进行扩容,扩容前判断这个较大的数是否大于elementData的长度,如果大于就扩容,第一次扩容时,实现是这个样子

在这里插入图片描述然后将这个元素放入对应的位置,并且size+1,下图为此时的elementData和list,从这里就可以看出来list和elementData的区别,从而理解容量的概念。

在这里插入图片描述

当第十一次add时这时当前的size为10

在这里插入图片描述

这个时候这个方法就会在默认容量和size+1个选择较大的数字为下一步扩容做准备,进入grow方法,进行一个具体的扩容操作

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

int oldCapacity = elementData.length;  //记录当前的elementData的长度
int newCapacity = oldCapacity + (oldCapacity >> 1);  //计算新的长度,即新的长度为原来的1.5倍
if (newCapacity - minCapacity < 0)  
    newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0) //超过最大的范围时另行处理
    newCapacity = hugeCapacity(minCapacity);  
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);  //数据转移复制

在这里插入图片描述

当执行完复制后可以看到elementData的长度扩大为15(即10的1.5倍 ),然后再将元素放入相应的位置上。

在这里插入图片描述

控制台也看到第十一次添加后list的容量为15。

在这里插入图片描述

使用addAll(Collection<? extends E> c)方法添加

先看一下结果

在这里插入图片描述

这里为什么会是11呢?让我们进入debug查看一下

在这里插入图片描述

同样是进入这个方法这个时候取;两者中较大者11,接着进行下一步,

在这里插入图片描述

这里看得出来计算出来新的容量为11

在这里插入图片描述

打印出来的也就是11

在这里插入图片描述那么写一个这样的例子

在这里插入图片描述

这个时候就可以看出结论来,

在这里插入图片描述

总结一下:

  1. 当使用add方法添加元素时,list扩容后的大小是上一次的大小的1.5倍(当然这里的扩容指的是经过第一次扩容后容量为10之后的再发生的扩容行为)。
  2. 当使用addAll方法添加元素时,list会进行一次性扩容,不会因为扩容后容量不够而再次扩容,最后一个容量为16的就是一个例子,他不会扩容到15然后再扩容到15 + 15>>1 = 22,而是一次到位,也就是说,使用addAll方法,没有元素时,扩容为 Math.max(10, 实际元素个数),有元素时为 Math.max(原容量的1.5 倍, 实际元素个数)
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-04-15 00:35:02  更:2022-04-15 00:39:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:52:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码