ArrayList 源码(基于Java1.8)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ArrayList 源码(基于Java1.8)相关的知识,希望对你有一定的参考价值。

ArrayList 基于数组实现,也就是类对变量 Object[]系列操作,封装为常用的add,remove,indexOf, contains本质是通过 size 计数器对数组进行系列的操作实现

add 方法和 toArray 也是借助 Arrays 工具类完成

还有很有意思的地方就是add的扩容方法 ensureCapacityInternal() 就会增加50%容量,

因为底层数组是不可变的,所以add实际上是通过Arrays工具再拷贝扩容后长度的数组,然后覆盖当前数组

预设集合长度是最优的操作,今天看源码才明白原理,ArrayList默认构造器为内部数组定义的长度为10,当list超出指定集合的时候,ArrayList会操作自动扩容,

扩容的方法是使用Arrays.copyOf方法重新构造新的数组,然后将旧数组的数据全部拷贝到新的数组里面,重新生成,再拷贝数组,消耗是巨大的,这也导致了 ArrayList 天生的缺点,插入删除元素慢

技术分享
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {

    private static final long serialVersionUID = 8683452581122892189L;

    private static final int DEFAULT_CAPACITY = 10;

    private static final Object[] EMPTY_ELEMENTDATA = {};

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    transient Object[] elementData; // non-private to simplify nested class access

    private int size;
技术分享

源码中可以看到,ArrayList继承抽象类AbstractList,实现List接口,RandomAccess, Cloneable, Serializable等接口主要用于标识,并没有很大作用

DEFAULT_CAPACITY = 10 是集合的默认初始化长度,我们常用new ArrayList<>()构造,其实就是创建一个长度为10的Object[]数组

size 为计数器,记录当前数组的长度

技术分享
public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

 

以上是关于ArrayList 源码(基于Java1.8)的主要内容,如果未能解决你的问题,请参考以下文章

java1.8特性之多重排序简单示例

ubuntu怎么装java1.8

基于 SpringBoot 的仿豆瓣平台源码分享

基于 SpringBoot 的仿豆瓣平台源码分享

基于JDK8的ArrayList源码分析

ArrayList源码分析(基于JDK1.8)