ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ArrayList的自动扩容机制

2021-04-11 17:32:59  阅读:188  来源: 互联网

标签:扩容 int ArrayList elementData newCapacity minCapacity 自动 集合


ArrayList的继承体系

ArrayList 是 java 集合框架中比较常用的数据结构。继承自 AbstractList,实现了 List 接口。基于数组实现容量大小动态变化。同时还实现了 RandomAccess、Cloneable、Serializable 接口,所以ArrayList 是支持快速访问、复制、序列化的。

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

ArraList的扩容机制

首先看下ArrayList的Add方法:

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

其中ensureCapicityInternal()是添加元素时调用的扩容方法:

        如果使用默认的构造参数的话,则选择minCapacity和DEFAULT_CAPACITY中较大的一个来作为最小的初始容量,大家可能奇怪,既然判断了初始化这一说,为何还会有传入的minCapacity,
和DEFAULT_CAPACITY比较这一说,是因为ensureCapacityInternal也会被addAll调用

解释:当集合对象第一次添加元素的时候,集合大小扩容为10(若使用addAll方法添加元素,则初始化大小为10和添加集合长度的较大值)

private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        ensureExplicitCapacity(minCapacity);//非初始化状态时,判断集合是否需要扩容

    }

当集合初始化完毕后,再次添加元素时。调用其ensureExplicitCapacity方法:

解释:if (minCapacity - elementData.length > 0),如果最小需要空间比elementData的内存空间要大,扩容,调用核心方法grow()

private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

核心方法grow():

 解释:int oldCapacity = elementData.length;(获取原来装载对象集合的长度);

            int newCapacity = oldCapacity + (oldCapacity >> 1);(扩容至原来的1.5倍)

            if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;(如果扩容后仍小于添加集合的长度,新建集合长度为添加元素集合大小)

            if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);(若预设值大于默认的最大值检查是否溢出)

private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        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);
    }

总结

  • 1.ArrayList创建对象时,若未指定集合大小初始化大小为0;若已指定大小,集合大小为指定的大小;
  • 2.当第一次调用add方法时,集合长度变为10和addAll内容之间的较大值;
  • 3.之后再调用add方法,先将集合扩大1.5倍,如果仍然不够,新长度为传入集合大小;

标签:扩容,int,ArrayList,elementData,newCapacity,minCapacity,自动,集合
来源: https://blog.csdn.net/qq_44624536/article/details/115601853

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有