Java使用数组实现ArrayList的动态扩容的方法

Java中的ArrayList是一种基于动态数组实现的动态数据结构,其容量可以动态地增加或缩减。在使用ArrayList时,如果我们需要添加更多元素到列表中,就需要涉及扩容操作。下面详细介绍在Java中使用数组实现ArrayList的动态扩容的方法。

  1. 定义一个数组来保存列表元素
    在Java中,我们可以通过定义一个数组来保存ArrayList的元素。数组的大小和ArrayList的容量有一一对应的关系,所以当需要添加更多元素时,我们需要使用动态地增加数组的大小。
Object[] elementData;
  1. 添加元素时,检查数组是否已满,如已满则进行扩容
    在添加元素时,我们需要检查当前数组是否已满。如果已满,我们需要进行扩容操作。在Java中,使用Arrays.copyOf方法来实现数组的扩容,其内部实现是创建一个新的数组,并将原有的元素全部拷贝到新的数组中,最后将新的数组作为ArrayList的内部数组。
public void add(E e) {
    ensureCapacity(size + 1);
    elementData[size++] = e;
}

private void ensureCapacity(int minCapacity) {
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);
}

在以上代码中,ensureCapacity方法用于检查是否需要扩容,如果需要则调用grow方法进行扩容。grow方法首先计算新的容量,然后使用Arrays.copyOf方法创建新的数组并拷贝原有元素到新的数组中。

  1. 数组的动态扩容策略
    Java中的ArrayList采用增加1.5倍容量的策略进行动态扩容。当需要添加元素时,如果当前数组已满,则采用以下公式计算新的容量。

newCapacity = oldCapacity + (oldCapacity >> 1);

如果计算得到的新容量仍然不够,就使用要添加元素的个数作为新的容量。

下面是一个示例,展示如何在Java中使用数组实现ArrayList的动态扩容:

public class MyArrayList<E> {
    private Object[] elementData;
    private int size;

    public MyArrayList() {
        elementData = new Object[10];
        size = 0;
    }

    public void add(E e) {
        ensureCapacity(size + 1);
        elementData[size++] = e;
    }

    public E get(int index) {
        return (E) elementData[index];
    }

    public int size() {
        return size;
    }

    private void ensureCapacity(int minCapacity) {
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

    private void grow(int minCapacity) {
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity > Integer.MAX_VALUE - 8)
            newCapacity = Integer.MAX_VALUE - 8;
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    public static void main(String[] args) {
        MyArrayList<Integer> list = new MyArrayList<>();
        for (int i = 0; i < 100; i++) {
            list.add(i);
            System.out.println("size=" + list.size() + ", capacity=" + list.elementData.length);
        }
    }
}

以上代码中,MyArrayList是自定义的ArrayList实现类,其中有一个elementData数组来保存元素。在main方法中,我们添加100个元素,每次添加一个元素时,都会输出当前列表的大小和容量。运行结果如下:

size=1, capacity=10
size=2, capacity=10
size=3, capacity=10
size=4, capacity=10
size=5, capacity=10
size=6, capacity=10
size=7, capacity=10
size=8, capacity=10
size=9, capacity=10
size=10, capacity=10
size=11, capacity=15
size=12, capacity=15
size=13, capacity=15
size=14, capacity=15
size=15, capacity=15
size=16, capacity=15
size=17, capacity=15
size=18, capacity=15
size=19, capacity=15
size=20, capacity=15
size=21, capacity=31
size=22, capacity=31
size=23, capacity=31
size=24, capacity=31
size=25, capacity=31
size=26, capacity=31
size=27, capacity=31
size=28, capacity=31
size=29, capacity=31
size=30, capacity=31
size=31, capacity=46
size=32, capacity=46
size=33, capacity=46
size=34, capacity=46
size=35, capacity=46
size=36, capacity=46
size=37, capacity=46
size=38, capacity=46
size=39, capacity=46
size=40, capacity=46
size=41, capacity=69
size=42, capacity=69
size=43, capacity=69
size=44, capacity=69
size=45, capacity=69
size=46, capacity=69
size=47, capacity=69
size=48, capacity=69
size=49, capacity=69
size=50, capacity=69
size=51, capacity=103
size=52, capacity=103
size=53, capacity=103
size=54, capacity=103
size=55, capacity=103
size=56, capacity=103
size=57, capacity=103
size=58, capacity=103
size=59, capacity=103
size=60, capacity=103
size=61, capacity=154
size=62, capacity=154
size=63, capacity=154
size=64, capacity=154
size=65, capacity=154
size=66, capacity=154
size=67, capacity=154
size=68, capacity=154
size=69, capacity=154
size=70, capacity=154
size=71, capacity=231
size=72, capacity=231
size=73, capacity=231
size=74, capacity=231
size=75, capacity=231
size=76, capacity=231
size=77, capacity=231
size=78, capacity=231
size=79, capacity=231
size=80, capacity=231
size=81, capacity=346
size=82, capacity=346
size=83, capacity=346
size=84, capacity=346
size=85, capacity=346
size=86, capacity=346
size=87, capacity=346
size=88, capacity=346
size=89, capacity=346
size=90, capacity=346
size=91, capacity=519
size=92, capacity=519
size=93, capacity=519
size=94, capacity=519
size=95, capacity=519
size=96, capacity=519
size=97, capacity=519
size=98, capacity=519
size=99, capacity=519
size=100, capacity=519

可以看到,当添加第11个元素时,容量从10扩充到了15;当添加第21个元素时,容量从15扩充到了25;当添加第41个元素时,容量从31扩充到了46;当添加第61个元素时,容量从69扩充到了103;当添加第81个元素时,容量从154扩充到了231;当添加第91个元素时,容量从231扩充到了346。可以看到,容量的增长是按照1.5倍递增的,并且每次扩充之后容量都能够满足当前大小的需求,而不是只刚好满足。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java使用数组实现ArrayList的动态扩容的方法 - Python技术站

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

相关文章

  • Eclipse连接Mysql数据库操作总结

    下面是Eclipse连接Mysql数据库操作的完整攻略: 1. 导入Mysql驱动 在Eclipse中,我们需要先导入Mysql的驱动库。可以从Mysql的官网下载最新的JDBC驱动程序(通常是一个jar包),然后将其导入到项目的classpath路径下面即可。 <!– 导入Mysql驱动 –> <dependency> <…

    Java 2023年5月20日
    00
  • 使用maven自定义插件开发

    让我来为您详细讲解“使用maven自定义插件开发”的完整攻略。 1. 简介 Maven是一个Java项目管理工具,它可以帮助我们更方便地管理项目依赖、构建等工作。Maven的自定义插件可以帮助我们更好地满足自己的需求,提高项目的开发效率。本文主要介绍如何使用Maven自定义插件开发,并提供两个基本案例演示。 2. 开发步骤 自定义Maven插件的开发步骤包括…

    Java 2023年5月20日
    00
  • Java解析JSON数据时报错问题解决方案

    下面是“Java解析JSON数据时报错问题解决方案”的完整攻略,包含以下几个部分: 问题描述 在Java程序中使用第三方库解析JSON数据时,可能会出现各种报错,如JSON解析异常、数据类型不匹配等。 解决方案 针对这些问题,可以尝试以下解决方案: 1. 使用合适的JSON解析库 Java中有很多JSON解析库,如GSON、Jackson、Fastjson等…

    Java 2023年5月26日
    00
  • Java获取UTC时间的方法详解

    Java获取UTC时间的方法详解 什么是UTC时间 UTC(Coordinated Universal Time,协调世界时)是一种全球使用的时间标准,与格林威治标准时间(GMT,Greenwich Mean Time)等价。UTC时间是按照原子钟计时的,且与地球自转无关,因此是一种非常精确的时间标准。 Java中获取UTC时间的方法 要在Java中获取UT…

    Java 2023年5月20日
    00
  • JDBCTM 指南:入门2 – 连接

    JDBC是Java Database Connectivity的缩写,是Java编程语言的一种应用程序接口,用于规范客户端程序如何访问数据库。在本指南中,我们将介绍使用JDBC连接数据库的基础知识,包括配置JDBC驱动程序、建立数据库连接、执行SQL查询和更新请求等方面的内容。 配置JDBC驱动程序 在使用JDBC访问数据库之前,需要先配置JDBC驱动程序,…

    Java 2023年6月15日
    00
  • Java实现读取resources目录下的文件路径的九种方式

    Java实现读取resources目录下的文件路径通常有以下九种方式: 1. 使用ClassLoader的getResource()方法 在Java中,可以使用ClassLoader的getResource()方法获取resources目录下的文件路径。示例代码如下: URL resource = getClass().getClassLoader().ge…

    Java 2023年6月15日
    00
  • 微信小程序上传文件到阿里OSS教程

    下面是详细的“微信小程序上传文件到阿里OSS教程”,包含以下步骤: 1. 注册阿里云账号 如果还没有阿里云的账号,需要先注册一个账号,注册地址:https://account.aliyun.com/register/register.htm 2. 创建 OSS Bucket 登录阿里云控制台,进入对象存储 OSS 控制台,创建自己需要的 Bucket。具体操…

    Java 2023年5月23日
    00
  • Java Lock接口实现原理及实例解析

    Java Lock接口实现原理 Java Lock接口是Java中线程同步机制的一个重要组件。它可以替代传统的synchronized关键字实现线程同步,其主要实现原理是通过对一段代码区域进行加锁和解锁来实现线程同步。 Java Lock接口与synchronized关键字最大的区别就是它的锁具有可重入性。所谓可重入性,是指一个线程的已经获取的锁再次获取时会…

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