• Java集合:ArrayList扩容机制


    ArrayList继承了AbstractList类,实现了List接口
    其扩容开始于添加元素的add方法,其添加元素有两种方法:

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    
    public void add(int index, E element) {
         rangeCheckForAdd(index);
    
         ensureCapacityInternal(size + 1);  // Increments modCount!!
         System.arraycopy(elementData, index, elementData, index + 1,
                             size - index);
         elementData[index] = element;
         size++;
    }
    

    (重点1:扩容机制的核心) 可以发现两个方法都用了ensureCapacityInternal(),把数组长度加1,以确保能存下一个数据。
    首先,得到最小容量 如下源码所示,如果数组elementData为默认空数组(初始未设置容量),最小容量minCapacity置为:其(1)与DEFAULT_CAPACITY(10)的最大值,即10。否则保持minCapcity本身修改后的值。

    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
    
        ensureExplicitCapacity(minCapacity);
    }
    

    (重点2:进行是否扩容判断) 得到最小容量后,执行ensureExplicityCapacity(minCapacity),判断最小容量与当前数组长度的大小,大于当前数组长度,则执行grow方法()扩容,否则不扩容。

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
    
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    

    (重点3:grow方法:真正实现扩容的方法)
    新容量 = 旧容量的1.5倍
    如果 新容量 < 最小容量,则不需要扩容计算,新容量 = 最小容量;
    如果 新容量 > MAX_ARRAY_SIZE(即达到列表最大临界值),进入hugeCapacity(minCapacity) 再次进行判断:
    如果最小容量 > MAX_ARRAY_SIZE(最小容量达到列表最大临界值),返回Integer最大值;
    否则,返回MAX_ARRAY_SIZE(临界最大值)。

    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);
    }
    
    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }
    

    参考链接:
    https://blog.csdn.net/u010890358/article/details/80515284?utm_medium=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~default-2.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~default-2.no_search_link
    https://blog.csdn.net/qq_26542493/article/details/88873168

    步履不停
  • 相关阅读:
    bootloader
    Arm中的c和汇编混合编程
    Linux学习笔记(一)
    java按所需格式获取当前时间
    java 串口通信 rxtx的使用
    Tomcat数据库连接池
    面试
    复习 模拟call apply
    复习 js闭包
    复习js中的原型及原型链
  • 原文地址:https://www.cnblogs.com/yuanyunjing/p/15364669.html
Copyright © 2020-2023  润新知