【Java集合系列】ArrayList源码分析

【Java集合系列】ArrayList源码分析,第1张

【Java集合系列】ArrayList源码分析

本次学习分析ArrayList;
ArrayList作为util包下的常用类,因此必须学习源码的写作手法;

ArrayList源码分析 1 基本数据结构
 private static final int DEFAULT_CAPACITY = 10;

 private static final Object[] EMPTY_ELEMENTDATA = {};
 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
 transient Object[] elementData; 

ArrayList底层还是用数组实现,默认容量是10

2 添加元素及扩容代码分析
   public boolean add(E e) {
        modCount++;
        add(e, elementData, size); //size是ArrayList包含的元素个数
        return true;
    }
    private void add(E e, Object[] elementData, int s) {
        if (s == elementData.length)
            elementData = grow();
        elementData[s] = e;
        size = s + 1;
    }

begin,调用add(e) – > add(e, elementData, size),此时size=0,
grow()方法,elementData.length=0,因此会调用grow().

   private Object[] grow() {
        return grow(size + 1); // grow(minCapacity)
    }
    
   private Object[] grow(int minCapacity) {
        return elementData = Arrays.copyOf(elementData,
                                         newCapacity(minCapacity));
    }


private int newCapacity(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //
        if (newCapacity - minCapacity <= 0) {
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
                return Math.max(DEFAULT_CAPACITY, minCapacity);
            if (minCapacity < 0) // overflow
                throw new OutOfMemoryError();
            return minCapacity;
        }
        return (newCapacity - MAX_ARRAY_SIZE <= 0)
            ? newCapacity
            : hugeCapacity(minCapacity);
    }

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

grow方法,然后进入newCapacity方法。
第一次进入newCapacity(1),oldCapacity = elementData.length;此时oldCapacity是0,因此执行newCapacity方法中的第一、二个if后,会 return Math.max(DEFAULT_CAPACITY, minCapacity);即返回默认大小10;它的流程是:
add(e) - - - > add(e, elementData, size), 第一次size=0

grow() - - - > grow(size+1) 这里的size+1会赋值给形参minCapacity - - - > newCapacity(minCapacity) ,第一次返回默认大小10- - - > System.copyOf();

第二次执行element.length=10; 所以在执行add - - - > add(e, elementData, s)后就直接保存元素。

当size=10(0-9的元素已经保存了数据)的时候,此时s == elementData.length 便要扩容,执行grow()方法;扩大为原来1.5倍。

两个重要方法
System.arraycopy()
System.copyOf(数组,新长度);//新申请 新长度的大小空间,然后报origin数组的数据复制到copy数组中,
删除 *** 作
    public E remove(int index) {
        Objects.checkIndex(index, size);
        final Object[] es = elementData;

       @SuppressWarnings("unchecked") E oldValue = (E) es[index];
        fastRemove(es, index);

        return oldValue;
    }
//快速删除方法,私有的
   private void fastRemove(Object[] es, int i) {
        modCount++;
        final int newSize;
        if ((newSize = size - 1) > i)
            System.arraycopy(es, i + 1, es, i, newSize - i);
        es[size = newSize] = null;
    }

♥️✌️✌️春招准备第一篇博客

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5712689.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存