jdk源码ArrayList学习体会分析二

来源:互联网 发布:tim linux 编辑:程序博客网 时间:2024/06/04 00:58

ArrayList就是一个可调整大小的数组,即可动态的增减元素,改变数组大小。

以下是我阅读ArrayList源码的一点心得及总结:

首先,ArrayList定义:


可以看出ArrayList是支持泛型的ArrayList<E>,继承AbstractList,实现LIst,RandomAccess, Cloneable, java.io.Serializable接口

其中LIst也是支持泛型的,定义了列表必须实现的方法。

RandomAccess是个标记接口,无内容。如果List子类实现了RandomAccess接口,那就表示它能够快速随机的访问元素。

即:ArrayList实现RandomAccess接口,意义在于访问列表时,可以选择最佳方式快速的访问。

Cloneable标识接口,无内容。实现Cloneable类,可以调用Object.clone()方法返回对象的浅拷贝。

实现java.io.Serializable接口即可启用序列化功能。

ArrayList属性,2个私有属性


elementData是ArrayList存储的元素,size是ArrayList的大小。

实现java.io.Serializable接口,将不需要序列化的属性前加上transient关键字,序列化对象时,该属性就不会被序列化到指定的目的地中。


ArrayList提供了3个构造方法以满足不同需求:

先看前2个:


第一个构造方法是根据传递的initialCapacity来初始化数组的大小,如果传递的值小于0 ,就会抛出参数不合法提示。

第二个构造方法调用第一个构造方法传入10来初始化数组,即数组大小为10.

下面来看第三个构造方法,如下:


将传递的集合转换成数组返回给elementData(返回的如果不是Object[],则调用Arrays.copyOf方法转为Object[])

Arrays.copyOf方法的具体实现:


首先是分配一个大小为newLengthd的Object,再调用系统方法arraycopy将original拷贝到copy中,从位置0开始拷贝newLength个长度,拷贝到copy中也是从位置0开始赋值,最后返回copy.


ArrayList的其他方法:

ensureCapacity(int minCapacity)方法,确保数组的最小容量


传递参数为minCapacity,用oldCapacity记下原来数组的大小,如果minCapacity的值大于原来数组大小,则需要增加容量来确保数组的容量够用。

如何增加的 呢?

使用(oldCapacity * 3)/2 + 1赋值给新的容量newCapacity,那么接下来就该判断新容量newCapacity和传递的minCapacity的大小了。如果newCapacty小于minCapacity,则说明定义的新容量太小不能满足要求,所以要把minCapacity赋值给新容量newCapacty作为原来数组的大小;否则说明新容量newCapacty大于传递的参数,可以满足要求,这样就保证来了最终的newCapacity是大于或等于传递的minCapacity的,即copy返回的最终elementData数组不会出现越界问题。

最后调用Arrays.copyOf方法把newCapacity作为数组的大小copy返回给elementData。


IndexOf()方法:


遍历数组elementData,如果传递的O在数组中存在即和某个值相等,则返回所在索引即【0,size-1】,若不存在则返回-1.

注:若存在多个,则返回第一次出现的位置(满足条件的lowest),是顺序遍历的。

与之相反的是lastIndexOf()方法:


遍历数组返回最后一次和O相等的位置,所以倒序遍历数组找第一次出现O的位置即可,并返回下标。


add(E e)在数组尾部添加元素


首先调用ensureCapacity(size+1)方法确保数组容量,上面已经解释过,调用此方法传递size+1,则数组elementData容量至少是size+1,即至少容量增加了一个,所以再给elementData[size}=e不会越界,赋值后属性size++自增1.

add(int index,E element),添加指定元素到指定位置:


首先判断传递的指定位置index是否在合理范围内【0,size】,若不满足则抛出越界异常(如果等于size,则是在数组尾端添加元素element)

调用ensureCapaCity(size+1)保证数组容量至少增加1,之后调用System.arrayCopy()方法,将数组elementData从特定位置index开始拷贝size-index个长度(即index之后的元素)到elementData数组(拷贝的元素赋值从index+1开始),换句话说就是把从index位置(如是第5个元素)后的元素全部后移一位(放到第6位),依次类推共size-index个元素直至把elementData[size-1]最后一个元素放到新的elementData[size]中,此时size还是原来的size大小。

再把指定元素放到index(第5个位置)上,即elemnetData[index]=elment;最后size自增1.


删除指定位置的元素remove(int index):


与添加指定元素到指定位置类似,RangeCheck(index)检查index是否在合理的范围内【0,size-1】

muMoved=(size-1)-index;意为需要移动的元素个数,如果要删除的是第一个位置0,则需要把size-1个元素即除去原本的第一个元素,其他所有后面的元素均要向前移动一位(这里不是真的移动,是吧后面 的index+1位置元素拷贝到index位置上,形象的理解为向前移动)。最后size--自减1,最后空出的位置赋值为null.返回删除的元素oldValue.

一点小小理解,暂时写到这。

2 0
原创粉丝点击