关于ArrayList

List概述

List是一个列表结构抽象定义,有序的,可对其中每个元素的插入位置进行精确地控制,可以通过索引来访问元素,遍历元素。包括函数的有:添加元素,删除元素,判断是否包含元素等等重要函数。

 
ArrayList
概述
     ArrayList的底层数据结构是用数据结构实现得,申请的内存是连续得,访问数据比较快。添加元素时,如果JVM连续内存不足执行垃圾回收。添加元素大于数组大小,ArrayList会创建新数组并且老数组里元素复制到新数组中,然后添加新元素到最后一个元素后面。
 
类图
 

 

 

构造
实例化ArrayList对象时,并不知道要List的大小边界,此时可以使用一个无参数构造函数,ArrayList中有一个类型为Object[]的DEFAULTCAPACITY_EMPTY_ELEMENTDATA空数组,DEFAULTCAPACITY_EMPTY_ELEMENTDATA赋值给元素存储对象数组elementData。
 
 
若知道边界大小实例化ArrayList时,使用带初始容量initalCapacity的构造函数。initalCapacity>0时,数组长度为initalCapacity;initalCapacity=0,数组为一个空数组;initalCapacity<0,抛出IllegalArgumentException异常。见如下源码:
 
 
size变量
     指明ArrayList实例当前含有多少元素。
 
元素添加
     使用无索引的add函数进行说明。首先ensureCapacityInternal函数确认内部容量大小
 

 

 ensureCapacityInternal 调用calculateCapacity函数计算容量大小。

 
 calculateCapacity函数功能计𥫠算容量,elementData数组为空时,计算结果DEFAULT_CAPACITY和minCapacity其中最大值。
 
ensureExplicitCapacity函数,modCount变量+1,minCapacity大于元素数组大小调用grow函数。
 
 
grow函数:计算ArrayList容量公式:newCapacity = oldCapacity + (oldCapacity >> 1),即新容量大小=老容量大小*1.5。如果计算的newCapacity-minCapacity小于0,minCapacity 赋值给newCapacity;newCapacity-MAX_ARRAY_SIZE>0时,Integer.MAX_VAULE赋值给newCapacity。使用Arrays.copyOf函数把ArrayList元素复制到新数组中,新数组长度为newCapacity。

 
grow函数注意:
     1)ArrayList是基于连续内存的数组结构,构造ArrayList实例时,最好能确认数组的边界避免减少数组复制,尤其ArrayList元素多时,调用add函数且大于容量大小时 ,非常耗时。
 
add带索引函数
     rangeCheckForAdd函数检查索引。System.arraycopy函数移动元素,index索引元素及之后的元素都向后移一个位置。然后index索引位置放入element元素。
 
 
索引获取元素
 get函数传递index索引值获取元素
 

 

 调用rangeCheck函数检查索引值,index值不能size变量,否则抛出IndexOutOfBoundsException异常。

 

 

 elementData函数返回index索引对应的元素,并且转化E类型。

 
 
删除元素
remove(int index)
调用rangeCheck函数检查index索引。通过调用elementData函数获取被删元素,计算移动元素数量numMove=size-index-1,调用System.arraycopy函数移动元素。元素变量减少,size-1。size索引位置对应的设置为null.最后返回被删元素。
 
 
 
remove(Object o) 
o为null时,比较元素值为null,调用fastRemove函数。o不为null时,比较o与元素哈希值,如果哈希值相等调用fastRemove函数。remove方法返回的boolean类型的值。
 
fastRemove函数主要功能移动元素,size索引位置设置为null。size可以不设置null吗?其实是可以得,但不设置null,elementData引用已删元素,GC发现已删元素存在引用不会对元素进行回收。所以设置为null有利于GC回收,释放无用对象,有效利用内存空间。
 
 
总结
1)获取元素操作耗时少,响应快。
2)新增,删除操作时,若存在数组长度不够创建新数组的过程,耗时长,响应慢。尤其是大ArrayList实例场景。
 
重要辅助函数
System.arraycopy 元素移动
Arrays.copyOf  ArrayList 转化成Object[] 
posted @ 2019-12-22 18:10  文双萍  阅读(342)  评论(0编辑  收藏  举报