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日

相关文章

  • Jvisualvm监控远程SpringBoot项目的过程详解

    以下是“JVisualVM监控远程SpringBoot项目的过程详解”的完整攻略: 简介 JVisualVM是Java虚拟机监视器和性能分析工具的图形化界面,它提供了一组用于分析Java应用程序运行的工具,包括CPU和堆剖析,线程和类查看器,GC鉴定工具等等,可以方便地监控Java应用的性能,分析应用的性能瓶颈。 Spring Boot为开发者提供了一种更简…

    Java 2023年5月20日
    00
  • apache .htaccess文件详解和配置技巧总结

    下面就来详细讲解一下“apache .htaccess文件详解和配置技巧总结”的完整攻略。 一、什么是 .htaccess 文件? 在 Apache 服务器上,.htaccess 文件是一个可以被用来改变服务器配置的配置文件。它可以被放在网站的根目录或者任何需要特殊配置的目录中,而不需要修改服务器的主配置文件(httpd.conf)。 二、.htaccess…

    Java 2023年6月15日
    00
  • Java面向对象基础知识之抽象类和接口

    Java面向对象基础知识之抽象类和接口 在Java面向对象编程中,抽象类和接口是重要的概念。本攻略将详细讲解抽象类和接口的基础知识,包括定义、用法、区别等内容,并提供两个示例说明。 抽象类 定义 抽象类是一种特殊的类,它不能被实例化,只能被继承。它的主要作用是作为其他类的基类,可以定义一些共性的属性和方法,并留下一些抽象方法的定义,让子类去实现。抽象方法没有…

    Java 2023年5月26日
    00
  • JavaWeb实现图形报表折线图的方法

    下面就是JavaWeb实现图形报表折线图的方法的完整攻略: 1. 准备工作 在实现JavaWeb图形报表折线图前,我们需要先准备好以下资源: 前端使用的图表库,例如ECharts、Highcharts等; 后端使用的JavaWeb框架,例如Spring、Struts2等; 数据库,用于存储数据; 数据库连接池,用于连接数据库。 2. 使用ECharts绘制折…

    Java 2023年6月15日
    00
  • GZIP压缩Tomcat并提升web性能过程图解

    下面我将为您详细讲解如何使用GZIP压缩Tomcat并提升Web性能的完整攻略。 1. 为什么需要GZIP压缩 在Web应用中,传输的大部分数据都是文本类型,如HTML、CSS、JavaScript、JSON或XML等。这些文本类型的数据在传输时,占用了大量的网络带宽资源和传输时间,从而导致网站的响应速度变慢,影响用户体验。为了解决这个问题,可以使用GZIP…

    Java 2023年6月15日
    00
  • SpringBoot整合SpringCloud的过程详解

    下面我将详细讲解“SpringBoot整合SpringCloud的过程详解”的完整攻略。 1. 前置知识 在开始整合 SpringBoot 和 SpringCloud 前,需要先掌握以下技术: 熟悉 SpringBoot 和 SpringCloud 的基础知识和机制; 熟练掌握分布式系统的编程思想和设计模式; 对于分布式系统的弹性设计、服务注册与发现、负载均…

    Java 2023年5月15日
    00
  • 微信小程序后端(java)开发流程的详细步骤

    下面是“微信小程序后端(java)开发流程的详细步骤”的完整攻略。 1. 准备工作 1.1 确定开发语言和开发工具 Java是一种常用的后端开发语言,常用的开发工具有Eclipse、IntelliJ IDEA等,选择一款适合自己的工具进行开发。 1.2 搭建开发环境 安装JDK、Apache Maven、MySQL等开发环境,保证开发环境正常运行。 1.3 …

    Java 2023年5月23日
    00
  • Java发送form-data请求实现文件上传

    下面是详细的讲解“Java发送form-data请求实现文件上传”的完整攻略: 介绍 HTTP协议中有多种方式可以实现文件上传,其中 multipart/form-data 是一种常见的方式,可以通过 POST 方法将表单数据和文件一同上传到服务器。在Java中,我们可以通过一些开源库或工具来实现这个过程,比如 HttpClient,OkHttp,RestT…

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