• Java ArrayList扩容机制


    • ArrayList中维护了一个Object类型的数据,elementData
    •  transient Object[] elementData;
      
    •  //transient表示该对象不会被序列化(序列化——把Java对象转换为字节序列的过程)
      
    •   当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第一次添加,则扩容为10,如果需要再次扩容,则扩容为elementData为1.5倍
      
    •  如果使用的是指定大小的构造器,则初始化elementData容量为指定大小,如果需要扩容,则直接扩容为elementData为1.5倍
      

    通过下列示例来说明该机制

    package gather.collection.list;
    
    import java.util.ArrayList;
    @SuppressWarnings({"all"})//抑制警告
    /**
     * @Author Blueshadow
     * @Date 2021/7/20 11:00
     * @Version 1.0
     */
    public class list {
        public static void main(String[] args) {
            ArrayList list = new ArrayList();//elementData数组初始大小为0
            for (int i = 0; i < 10 ; i++) {
                list.add(i);
            }
    
            list.add(100);
            list.add(200);
            list.add(null);
            for (Object object : list) {
                System.out.println(object);
            }
        }
    }
    
    

    底层源码说明

    第一次初始化,创建了一个名为elementData的Object类型的数组,该数组可以存放多种类型的数据,主要是通过包装类来实现。

    public ArrayList() {
            this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
        //private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//创建Object类型数组
        //创建了一个空数组,并将数组命名为 elemenrData
        }
    

    下一步:在执行list.add(1)时,会先进性判断,是否需要扩容,然后再执行赋值操作。

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

    下一步:判断是空,则给数组赋予一个最小容量,第一次add,最小容量为minCapacity。

    private void ensureCapacityInternal(int minCapacity) {
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//先确定elementData是否是一个空数组:
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);//先确定最小容量minCapacity(第一次扩容为10)
            }
            ensureExplicitCapacity(minCapacity);//真正确定是否扩容
        }
    

    下一步:进行底层的扩容。

    private void ensureExplicitCapacity(int minCapacity) {
            modCount++;//记录当前集合被修改的次数
    
            // overflow-conscious code
            if (minCapacity - elementData.length > 0)//如果elementDara容量不够,就调用grow方法进行扩容
                grow(minCapacity);//进行底层的扩容
        }
    

    第一次扩容最后一步:底层按照1.5倍进行扩容

    
     private void grow(int minCapacity) {
            // overflow-conscious code
            int oldCapacity = elementData.length;//第一次oldCapacity=0
            int newCapacity = oldCapacity + (oldCapacity >> 1);//原先数组大小+原先数组大小/2
            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);//elementData={},使用该方法将newCapacity赋值给elementData
        }
    
  • 相关阅读:
    洛谷-P1496 火烧赤壁
    洛谷-P5638 【CSGRound2】光骓者的荣耀
    Java多线程实现
    linux安装mysql 8的完整过程
    tomcat安装
    C#之Null
    JToken
    初识算法之线性表---双向列表
    初识算法之线性表---链表定义/结构(2)
    初识算法之线性表---链表定义/结构(1)
  • 原文地址:https://www.cnblogs.com/nanfengashuai/p/15036301.html
Copyright © 2020-2023  润新知