Java ArrayList扩容机制原理深入分析

Java ArrayList扩容机制原理深入分析

在 Java 中,ArrayList 是一种动态数组,它可以自动扩容以适应数据的增长。了解 ArrayList 扩容机制的原理,有助于我们更好地理解和使用 ArrayList,提高代码效率。

ArrayList 扩容机制

ArrayList 内部使用数组来存储元素,当向 ArrayList 中添加元素时,如果当前数组已满,就需要扩容。下面是 ArrayList 扩容的基本流程:

  1. 获取当前 ArrayList 的容量 capacity 和当前 ArrayList 已存储的元素个数 size;
  2. 判断当前数组是否已满,即 size == capacity
  3. 如果数组已满,创建一个新的容量是原来容量 1.5 倍的数组,并将原数组中的元素复制到新数组中;
  4. 新数组成为 ArrayList 的内部数组。

下面是一个简单的示例:

import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>(3);
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);
    }
}

在上面的例子中,我们创建了一个容量为 3 的 ArrayList,并往里面添加了 6 个元素。在添加第 4 个元素时,由于数组已满,系统调用了 grow() 方法进行扩容。下面是 grow() 方法的源码:

private void grow(int minCapacity) {
    // 获取当前 ArrayList 容量
    int oldCapacity = elementData.length;
    // 计算新容量大小
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    // 如果新容量不足以满足最小容量需求,就使用最小容量作为新容量
    if (newCapacity < minCapacity)
        newCapacity = minCapacity;
    // 创建新的数组,并将原数组的元素复制到新数组中
    elementData = Arrays.copyOf(elementData, newCapacity);
}

可以看到,在扩容时,系统会计算出新的容量大小,并将原数组的元素复制到新数组中,从而保证数据的顺序不变。需要注意的是,在计算新容量大小时,采用了位运算 >> 来代替除法,以提高代码效率。

另外,在调用 grow() 方法扩容时,如果我们向 ArrayList 中添加大量元素,扩容的次数可能很多,从而导致效率降低。因此,我们在使用 ArrayList 时,尽量预留一定的容量,避免频繁扩容。

下面是一个添加 100 000 个元素的例子,可以看到,在初始容量为 100 000 的情况下,并不会出现扩容的情况:

import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>(100000);
        for (int i = 0; i < 100000; i++) {
            list.add(i);
        }
    }
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java ArrayList扩容机制原理深入分析 - Python技术站

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

相关文章

  • 6000+字讲透ElasticSearch 索引设计

    ElasticSearch 索引设计 在MySQL中数据库设计非常重要,同样在ES中数据库设计也是非常重要的 概述 我们创建索引就像创建表结构一样,必须非常慎重的,索引如果创建不好后面会出现各种各样的问题 索引设计的重要性 索引创建后,索引的分片只能通过_split和_shrink接口对其进行成倍的增加和缩减 主要是因为es的数据是通过_routing分配到…

    Java 2023年5月11日
    00
  • 浅谈java 字符串,字符数组,list间的转化

    标题:浅谈Java字符串、字符数组、List间的转换 一、Java字符串、字符数组的转换 1.1 字符串转换为字符数组 可以使用 toCharArray() 方法将字符串转换为字符数组: String str = "hello"; char[] charArray = str.toCharArray(); // charArray = {…

    Java 2023年5月26日
    00
  • JSP过滤器防止Xss漏洞的实现方法(分享)

    实现JSP过滤器来防止XSS漏洞的方法如下: 在web.xml文件中添加过滤器配置 在web.xml文件中添加以下过滤器配置: <filter> <filter-name>XssFilter</filter-name> <filter-class>com.example.XssFilter</filter…

    Java 2023年6月15日
    00
  • SpringBoot整合Swagger框架过程解析

    下面为您详细讲解“SpringBoot整合Swagger框架过程解析”的完整攻略。 什么是Swagger? Swagger是一个开源框架,旨在简化 RESTful Web 服务的开发和文档化,它可以生成能描述API的 JSON、HTML等文档。它包含了一些工具,可以帮助开发人员设计、构建、文档化和使用 RESTful Web 服务。 SpringBoot整合…

    Java 2023年5月19日
    00
  • Java-String类最全汇总(下篇)

    下面是Java-String类最全汇总(下篇)的完整攻略。 一、简介 在Java编程中,String类是非常重要的一个类,用于表示字符串,并提供了一系列的操作字符串的方法。本文主要介绍了String类的一些常用操作方法,包括字符串的查找、替换、截取、比较等。 二、字符串查找 2.1 indexOf方法 该方法用于查找字符串中是否包含指定的子串并返回第一次出现…

    Java 2023年5月20日
    00
  • Spring MVC集成springfox-swagger2构建restful API的方法详解

    Spring MVC集成springfox-swagger2构建restful API的方法详解 Swagger 是一种流行的 API 文档工具,用于生成和管理 RESTful API 文档。在 Spring MVC 项目中,我们可以使用 springfox-swagger2 库来集成 Swagger,并使用 Swagger 来构建 RESTful API …

    Java 2023年5月18日
    00
  • Java SpringBoot @Async实现异步任务的流程分析

    针对你提出的这个问题,我将会按照以下步骤来给出完整的攻略: 介绍什么是SpringBoot @Async 讲解SpringBoot @Async的工作流程 提供两个示例,展示如何使用SpringBoot @Async来实现异步任务 1. 什么是SpringBoot @Async SpringBoot @Async是一个实现异步任务的开发框架。通过使用@Asy…

    Java 2023年5月20日
    00
  • springboot注入servlet的方法

    下面是详细讲解Spring Boot注入Servlet的方法的完整攻略。 1. 添加Servlet API依赖 在Spring Boot中使用Servlet必须要先添加Servlet API依赖。可以在pom.xml文件中添加以下依赖项: <dependency> <groupId>javax.servlet</groupId&…

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