聊一聊jdk1.8中的ArrayList 底层数组是如何扩容的

ArrayList 是一种常用的动态数组数据结构,底层依托于一个 Object[] 数组,当数组已满或者添加元素个数达到预分配的容量时,需要对数组进行扩容以继续添加元素。在 JDK1.8 中,时常听到关于 ArrayList 扩容的问题,接下来我将详细介绍 ArrayList 的底层数组如何扩容。

ArrayList 底层数组的定义

在 JDK1.8 的 ArrayList 中,底层数组的定义如下:

transient Object[] elementData; // 非私有的、仅在类 ArrayList 内部使用的数组,用于存储添加的元素。

其中,transient 关键字表示该字段不会被序列化。

ArrayList 底层数组扩容机制

ArrayList 中通过 ensureCapacityInternal 方法来判断是否需要对底层数组进行扩容,具体流程如下:

  1. 首先判断是否需要扩容。
private void ensureCapacityInternal(int minCapacity) {
        // 如果底层数组为空,则分配一个默认容量的数组
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        // 如果需要的最小容量大于现有数组容量,则需要扩容
        ensureExplicitCapacity(minCapacity);
}
  1. 调用 ensureExplicitCapacity 方法扩容。
private void ensureExplicitCapacity(int minCapacity) {
        // 修改扩容标志位
        modCount++;
        // 扩容时实际需要的最小容量为目前容量和需要的最小容量中的较大者
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
}

  1. grow 方法中,根据不同的情况进行扩容。
private void grow(int minCapacity) {
        // 获取此时底层数组的长度
        int oldCapacity = elementData.length;

        // 新容量为原来的1.5倍,向上取整
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;

        // 将底层数组复制到新的扩容底层数组中
        elementData = Arrays.copyOf(elementData, newCapacity);
}

扩容时,ArrayList 将底层数组的新容量计算为原来容量的1.5倍。同时,若所需的最小容量大于计算出的容量,则以所需容量为准。最后,通过调用 Arrays.copyOf 方法将原来的数组元素全部复制到新数组中去。

示例说明

示例一

下面是一段示例代码,演示 ArrayList 的扩容机制。

ArrayList<Integer> list = new ArrayList<>();

// 添加21个元素
for (int i = 1; i < 22; i++) {
  list.add(i);
}

System.out.println("当前数组容量:" + list.size());

输出结果如下:

当前数组容量:21

从结果可以看出,当添加元素个数达到数组容量的上限时,ArrayList 自动对底层数组进行扩容。

示例二

在一些场景下,我们需要对 ArrayList 进行优化,比如初始化时指定 ArrayList 的容量大小。下面是一段这样的示例代码:

ArrayList<Integer> list = new ArrayList<>(100);

// 添加100个元素
for (int i = 1; i < 101; i++) {
  list.add(i);
}

System.out.println("当前数组容量:" + list.size());

输出结果如下:

当前数组容量:100

从结果可以看出,当初始化时指定 ArrayList 的容量大小时,不需要进行数组扩容,大大提高了 ArrayList 的效率。

总结

ArrayList 底层数组的扩容机制是 ArrayList 实现动态数组的关键。扩容时,通过一定规则计算新的容量大小,并将原始数组复制到新的底层数组中,以完成实现动态数组的功能。在实际应用中,如有需要,可以根据不同情况对 ArrayList 进行一定程度的优化,以提高应用效率。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:聊一聊jdk1.8中的ArrayList 底层数组是如何扩容的 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • 轻松理解Java面试和开发中的IoC(控制反转)

    Java面试和开发中的IoC(控制反转) IoC指的是控制反转,实际上是一种设计模式,它的作用是降低程序之间的耦合性,从而提高代码的可重用性和可维护性。 什么是IoC? 在传统的开发方式中,程序之间的耦合度很高,因为它们都知道彼此的实现细节。例如,一个类需要使用另一个类的实例,通常是通过构造函数或属性设置的方式来完成的。 在IoC中,程序不再主动创建和维护对…

    Java 2023年5月24日
    00
  • Java 事务注解@Transactional回滚(try catch、嵌套)问题

    Java 事务注解@Transactional是用来标记一个方法需要被事务管理的,常用于对数据库进行操作时保证数据的一致性。在使用@Transactional标记方法时,我们可能会遇到回滚问题。 @Transactional的默认回滚行为 首先介绍一下@Transactional默认的回滚行为。如果一个被@Transactional标记的方法执行过程中抛出了…

    Java 2023年5月27日
    00
  • mybatis-generator自动生成dao、mapping、bean配置操作

    下面我详细讲解一下mybatis-generator自动生成dao、mapping、bean配置操作的完整攻略。 1. Mybatis-Generator简介 Mybatis-Generator是Mybatis的一个辅助插件,它可以自动生成Mybatis的DAO层、Mapping配置文件以及Java Bean类,用于简化开发人员的工作量。 2. 配置Myba…

    Java 2023年5月20日
    00
  • Java中的Native方法

    Java中的Native方法:完整攻略 理解Native方法 JNI(Java Native Interface)可以让Java应用程序在运行时,与C/C++语言编写的函数进行交互。因为Java虚拟机(JVM)不能直接运行非Java代码, JNI支持调用Native方法,Native方法是一些用其他编程语言(如C/C++)编写的方法。 Native方法是指C…

    Java 2023年5月23日
    00
  • Java实例化的几种方法总结

    Java实例化的几种方法总结 在Java中,对象是类的一个实例,而实例化则是创建这个实例的过程。Java提供了多种实例化对象的方法。以下是几种常见的实例化方法总结: 1. 使用new关键字 使用new关键字是最常见的实例化对象的方法。语法如下: ClassName objectName = new ClassName(); 其中,ClassName表示类的名…

    Java 2023年5月26日
    00
  • Spring Boot + thymeleaf 实现文件上传下载功能

    下面我将详细讲解“Spring Boot + Thymeleaf 实现文件上传下载功能”的完整攻略。 准备工作 在开始前,请确保你已经具备以下环境: JDK1.8及以上 Maven 3.0及以上 项目搭建 建立一个 Spring Boot 项目 可以通过 Spring Initializr 快速搭建,选择 Web 依赖和 Thymeleaf 模板引擎即可。 …

    Java 2023年6月15日
    00
  • shell脚本自动化创建虚拟机的基本配置之tomcat–mysql–jdk–maven

    下面是关于”shell脚本自动化创建虚拟机的基本配置之tomcat–mysql–jdk–maven”的完整攻略。 准备工作 在开始创建虚拟机之前,需要先完成以下准备工作: 选择合适的虚拟化软件,如VirtualBox,并安装在本地操作系统中。 准备虚拟机的镜像文件,如CentOS 7,下载好后可以在VirtualBox中导入镜像。 创建虚拟机 使用Vi…

    Java 2023年5月20日
    00
  • 详解SpringBoot简化配置分析总结

    详解SpringBoot简化配置分析总结 Spring Boot是一个流行的Java框架,可以帮助开发人员快速构建和部署应用程序。Spring Boot通过简化配置和提供自动配置来提高开发效率。本文将详细讲解Spring Boot简化配置的原理和实现,并提供两个示例,演示如何使用Spring Boot简化配置。 1. Spring Boot简化配置的原理 S…

    Java 2023年5月14日
    00
合作推广
合作推广
分享本页
返回顶部