java底层原理---ArrayList源码分析

java底层原理—ArrayList源码分析

引言

学习底层是为了更好的选择合适数据结构进行开发,这篇是为了讲解ArrayList底层原理的,同时也是总结一下自己的学习成果。

太多的文字让人看得眼花缭乱,废话不多说,上图解。

这是ArrayList的属性:

java底层原理---ArrayList源码分析

一、创建ArrayList对象,初始化过程

  1. ArrayList<String> list = new ArrayList<>();
    
  2. public ArrayList() {
         //this.当前数组=默认数组
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    
    • 给当前存储数据的数组创建出来,创建完毕。

二、调用add方法,添加数据过程

  1. list.add("admin");
    
  2. public boolean add(E e) {
        ensureCapacityInternal(size + 1); 
        //add方法把值"admin"传过来就是参数 e ,然后把值放进当前数组的下一个位置,但是我们这个当前数组还并没有被创建,我们就可以看看上面的方法
        elementData[size++] = e;
        return true;
    }
    
  3. 执行ensureCapacityInternal方法

    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
    
        ensureExplicitCapacity(minCapacity);
    }
    
    • 判断当前数组是否是空的元素数组(一般第一次都是)
    • Math.max()方法是判断两个参数的大小,返回较大的值
    • DEFAULT_CAPACITY是默认容量(10),一般第一次都是会返回默认容量
  4. 执行ensureExplicitCapacity方法

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
    
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    
    • 方法参数是最小容量
    • 如果最小容量(将要开辟的元素空间大小) - 当前数组的长度 > 0 那么就证明空间大小不够,就会执行grow扩容方法
  5. 如果容量不够则执行grow方法

    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);
    }
    
    • 此方法先是获取到了当前数组的长度大小,然后以 oldCapacity + (oldCapacity >> 1) 的方式每次扩容1.5倍的容量
    • 然后最后将当前数组给copy替换成新容量的数组,至此扩容完毕。

三、总结

  • ArrayList底层使用数组进行存储数据
  • ArrayList扩容机制每次扩容1.5倍
上一篇:Arraylist源码分析:


下一篇:java-jol GraphLayout输出中的“(其他)”是什么?