ArrayList知识详解

Posted yuan-zhou

tags:

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

简介

ArrayList是Java集合常用的数据结构之一,继承自AbstractList,实现了List,RandomAccess、Cloneable、Serializable等一系列接口,支持快速访问,复制和序列化。底层是基于数组实现容量大小动态变化,允许null值存在。

部分源码分析

ArrayList的底层是由数组实现

技术图片

默认size的初始大小为10:

技术图片

ArrayList定义了两个类常量数组:EMPTY_ELEMENTDATA(EE)和DEFAULTCAPACITY_EMPTY_ELEMENTDATA(DEE)

注释:EE,用于ArrayList空实例的共享空数组实例

DEE,用于默认大小空实例的共享空数组实例,将EE和DEE区分开,以便在添加第一个元素时知道要增加多少

技术图片

三个构造函数,包括一个无参构造和两个有参构造:

技术图片

技术图片

技术图片

 

注:无参构造创建的实例是DEFAULTCAPACITY_EMPTY_ELEMENTDATA,有参构造创建的实例是EMPTY_ELEMENTDATA

然后是add( )方法:

技术图片

当第一次调用add(E e)方法时,判断是不是无参构造方法创建的对象,如果是,则将DEFAULT_CAPACITY作为ArrayLiat的容量,此时minCapacity = 1

技术图片

还有其他add方法例如:

 addAll( Collection<? extends E> c )技术图片

add( int index, E element )

技术图片

等等....这些方法中都包含ensureCapacitylnternal( int Capacity )方法,确保无参构造在创建实例并添加第一个元素时,最小的容量是默认大小10。

  而有参构造创建空实例后,在add( E e )方法添加元素扩容情况是这样的:

新容量为旧容量的1.5倍

技术图片

在Java7中,ArrayList的构造方法只有EMPTY_ELEMENTDATA即EE, 而Java8中DEE代替了EE,但是原来的EE还存在,只是作用改变了:

技术图片

 

   当容量为0时,会创建一个空数组,赋值给elementData,当一个应用中有很多这样的ArrayList空实例时,就会有很多空数组,这样使用EMPTY_ELEMENTDATA就是为了优化性能,所有的ArrayList空实例都指向同一个数组。而DEE(DEFAULTCAPACITY_EMPTY_ELEMENTDATA)就是为了保证无参构造方法常见的实例在添加第一个元素时,最小的容量是默认的10.

 ArrayList的扩容

 以无参构造为例:

首先无参构造初以默认大小来始化内部数组

技术图片

然后是扩容,使用add( )方法

技术图片

ensureCapacityInternal方法中的size代表执行添加前的元素个数,通过现有的元素个数数组的容量进行对比,若需要扩容则扩容。

 ensureCapacityInternal(size + 1)就是将要添加的额元素放入数组中

 

扩容条件:若数组的长度eleentData的长度小于做小需要的容量minCapacity,就需要扩容

技术图片

扩容逻辑:

 技术图片

注:

1.  >>位运算,右移一位代表oldCapacity / 2,位运算效率更高

2.  JDK7后增加对元素个数的最大个数判断,MAX_ARRAY_SIZE为int最大值减去8

3.  复制元素方法扩容。使用延迟分配对象数组空间,当数组加满数组容量后才会按照1.5倍扩容。

 

以上是关于ArrayList知识详解的主要内容,如果未能解决你的问题,请参考以下文章

JAVA容器之ArrayList集合详解

Java基础| ArrayList详解与应用

Java集合知识总结详解

《C#零基础入门之百识百例》(八十三)ArrayList数组列表详解 -- 代码示例

《C#零基础入门之百识百例》(八十三)系统类ArrayList数组列表详解 -- 代码示例

ArrayList详解