JDK1.8 ArrayList 扩容详解

JDK1.8 ArrayList 扩容详解arraylist这个数据结构比较简单,总体来说,arraylist底层结构是数组,他的很多方法都是从数组上面演变而来的,下面分析下arraylist的扩容机制,每次在add()一个元素时,arraylist都需要对这个list的容量进行一个判断。如果容量够,直接添加,否则需要进行扩容。在1.8arraylist这个类中,扩容调用的是grow()方法,通过grow()方法中调用的Array…

大家好,又见面了,我是你们的朋友全栈君。

arraylist这个数据结构比较简单,总体来说,arraylist 底层结构是数组,他的很多方法都是从数组上面演变而来的,下面分析下arraylist的扩容机制,

每次在add()一个元素时,arraylist都需要对这个list的容量进行一个判断。如果容量够,直接添加,否则需要进行扩容。在1.8 arraylist这个类中,扩容调用的是grow()方法,通过grow()方法中调用的Arrays.copyof()方法进行对原数组的复制,在通过调用System.arraycopy()方法进行复制,达到扩容的目的

几个重要的初始化值

存储数组元素的缓冲区
// non-private to simplify nested class access
transient Object[] elementData; 
默认空数组元素
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
默认初始化容量
private static final int DEFAULT_CAPACITY = 10;
数组的大小
private int size;
记录被修改的次数
protected transient int modCount = 0;
数组的最大值
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8

几个重要的方法

一个空的构造方法

默认数组的长度为10
public ArrayList() {
    this.elementData  = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

添加元素的方法,

public boolean add(E e) {
扩充长度,在原来的大小上面加1
// Increments modCount!!
    ensureCapacityInternal(size + 1);  
添加元素
    elementData[size++] = e;
    return true;
}

确认内部容量

private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(
calculateCapacity(elementData, minCapacity));
}

计算容量

private static int calculateCapacity (Object[] elementData, int minCapacity) {
如果这个数组等于空,返回最大的容量,否则,还是原来的容量
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
    }

确认扩展容量

private void ensureExplicitCapacity(int minCapacity) {
修改次数加1
    modCount++;
如果容量不够,调用增加容量方法
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

扩展方法

private void grow(int minCapacity) {
    // overflow-conscious code
获取原来数组容量的长度
    int oldCapacity = elementData.length;
新增加的容量长度为原来容量的1.5倍
    int newCapacity = oldCapacity + (oldCapacity >> 1);
新容量比老容量小,那么新的容量就是老的容量
    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);
}

数组工具类中的复制方法

public static <T> T[] copyOf (T[] original, int newLength) {
    return (T[]) copyOf(original, newLength, original.getClass());
}

具体的复制方法

public static <T,U> T[] copyOf(U[] original, int newLength, 
Class<? extends T[]> newType) {
    @SuppressWarnings("unchecked")
获得者数组对象
    T[] copy = ((Object)newType == (Object)Object[].class)
        ? (T[]) new Object[newLength]
        : (T[]) Array.newInstance(newType.getComponentType(), newLength);

调用系统的方法增加数组容量
    System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
    return copy;
}

 

欢迎大家关注我的个人微信公众号了解更多内容:JDK1.8 ArrayList 扩容详解

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/142845.html原文链接:https://javaforall.net

(0)
上一篇 2022年5月22日 下午9:00
下一篇 2022年5月22日 下午9:00


相关推荐

  • xcode7中使用cocos2d-x3.8的webview控件

    xcode7中使用cocos2d-x3.8的webview控件

    2021年9月9日
    66
  • Velocity模板引擎

    Velocity模板引擎velocity 简介 velocity 介绍 Velocity 是一个基于 Java 的模板引擎 可以通过特定的语法获取在 java 对象的数据 填充到模板中 从而实现界面和 java 代码的分离应用场景 Web 应用程序 作为为应用程序的视图 展示数据 源代码生成 velocity 可用于基于模板生成 Java 源代码自动电子邮件 网站注册 认证等的电子邮件模板网页静态化 基于 velocity 模板 生成静态网页 velocity 结构 Velocity 主要分为 app context runtime

    2026年3月26日
    2
  • sigterm信号_一文吃透 PHP 进程信号处理

    sigterm信号_一文吃透 PHP 进程信号处理背景前两周老大给安排了一个任务,写一个监听信号的包。因为我司的项目是运行在容器里边的,每次上线,需要重新打包镜像,然后启动。在重新打包之前,Dokcer会先给容器发送一个信号,然后等待一段超时时间(默认10s)后,再发送SIGKILL信号来终止容器现在有一种情况,容器中有一个常驻进程,该常驻进程的任务是不断的消费队列里的消息。假设现在要上线,需要关杀掉容器,Docker给容器里跑的常驻进程发送一个…

    2025年8月12日
    6
  • 龙虾搭了不会用?你和高手只差这一个核心认知

    龙虾搭了不会用?你和高手只差这一个核心认知

    2026年3月16日
    3
  • Tair简介

    Tair简介简介 tair 是淘宝自己开发的一个分布式 key value 存储引擎 tair 分为持久化和非持久化两种使用方式 非持久化的 tair 可以看成是一个分布式缓存 持久化的 tair 将数据存放于磁盘中 为了解决磁盘损坏导致数据丢失 tair 可以配置数据的备份数目 tair 自动将一份数据的不同备份放到不同的主机上 当有主机发生异常 无法正常提供服务的时候 其于的备份会

    2026年3月18日
    2
  • firebird mysql_FIREBIRD浅历

    firebird mysql_FIREBIRD浅历firebird 可以说是这个世界上最小而又支持存储过程的数据库 才 3M 而已 如果做小型应用 比 mssql 桌面版也有 70 多 M mysql 20 30M 方便的多 一 数据库操作在开始 程序 Firebrid 2 0 中执行 FirebridISQL 出现 SQL gt 输入 SQL gt CREATEDATABA e sams fdb 回车提示错误 郁闷 一查资

    2026年3月26日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号