ArrayList源码翻译和阅读

目录

    • ArrayList前面的注释
    • 扩容机制
        • ensureCapacityInternal
        • ensureExplicitCapacity
        • grow
    • add方法
    • addAll方法
    • remove方法
    • batchRemove相关
    • 迭代器相关

ArrayList前面的注释

扩容机制

扩容机制主要由那么几个函数实现

private void ensureCapacityInternal(int minCapacity)
private void ensureExplicitCapacity(int minCapacity)
private void grow(int minCapacity)

依次讲一下

ensureCapacityInternal

区别于ensureExplicitCapacity:
这个函数是口头上说,最少需要多少容量,但是还没去查它自己到底有多少。
相当这个函数相当于一个人评估自己最少需要多少钱能满足生活,但仅仅是评估而已,他自己还不知道自己家里有多少钱。

 private void ensureCapacityInternal(int minCapacity) {
 		//判断一下当前的ArrayList是不是由无参构造函数构造的
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

※ 这个方法出现在 add() 和addAll()方法中,在 add()方法中调用 ensureCapacityInternal(size + 1), 因为add只是添加一个元素。
而在addAll()方法中则是 ensureCapacityInternal(size + numNew)。

※ 可以把这个方法看作是 “确保Arraylist的内部存储空间至少为 minCapacity”

※ 为什么要针对无参构造函数函数来做这样一个判断呢?因为无参构造函数的minCapacity比较特殊。通过其他构造函数生成的ArrayList,它们没有所谓的默认初始容量,所以要求的最小容量就是在add()或addAll()调用ensureCapacityInternal()方法时传入的minCapacity。

而无参构造函数不同,传入的minCapactiy可能会比DEFAULT_CAPACITY更小,那么此时就多给ArrayList分配点容量,所以 minCapacity = DEFAULT_CAPACITY ;而如果传入的minCapactiy比DEFAULT_CAPACITY更大,那么就和别的ArrayList一样了,分配minCapacity的容量就行了

ensureExplicitCapacity

这个函数就是在上一个函数评估的基础上,去查自己家里有多少钱,查出来如果家里的钱不够,那么就用 grow函数去增长,增长到 minCapacity

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

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

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);
    }

面试时记住这几个点就好:
① 增长为原来的1.5倍,如果增长后还是不够,那么就增长到minCapacity。那么这样的话,此时elementData数组是满的,没有剩余空间。
②如果数据太多,比MAX_ARRAY_SIZE还大了,就把空间容量扩大为Integer.MAX_VALUE

add方法

ArrayList有两个add()方法。

 public boolean add(E e) 
 就是把元素插到尾部
 public void add(int index, E element)
 把元素插到指定的地方,原来的那个元素后退一格

关键是 System.arraycopy 来实现数组的移位操作,这个函数可以在做算法题的时候用,很方便。

addAll方法

 public boolean addAll(Collection<? extends E> c)
 public boolean addAll(int index, Collection<? extends E> c)

remove方法

ArrayList有两个remove()方法。

public E remove(int index)
把指定下标的元素删除
 public boolean remove(Object o)
 从下标0开始循环,找到o后删掉。也就是说,只删除遇到的第一个

也是利用了System.arraycopy来对数组做整体移动。
之后再将最后一个元素作 elementData[size–] =null 的操作,让垃圾回收器去清理即可。

注意remove(Object o)中,对删除元素进行判断时,如果
o= =null ,则 利用 if(o==elementData[index]) 进行判断。
o!=null , 则利用 if(o.equals(elementData[index])进行判断。

batchRemove相关

迭代器相关

你可能感兴趣的:(源码阅读--集合)