java 集合源码分析之ArrayList

                                  ArrayList源码分析

1.简述

    ArrayList也就是List接口的可变长度数组的实现(Resizable-array implementation of the List interface),可以大体上认为是Vector的非线程安全实现。

2.源码分析

 2.1初始化

    构造函数三个:

   2.1.1创建默认长度为10的空集合

2.1.2创建指定初始容量的空集合

2.1.3创建包含指定集合的ArrayList

2.2存入元素

存入元素经常调用的是add(E e)方法,源码如下:

该集合类中有一个类变量数组Object[] elementData用来存储元素,当存储元素得时候以当前集合得size加1为参数进行容量校验。先判断elementData是不是等于DEFAULTCAPACITY_EMPTY_ELEMENTDATA,等于表示是第一次添加元素,这时最小容量为默认的容量值10.这时再与数组长度进行比较,如果最小容量大于数组长度则进行扩容,扩容后的容量为扩容前容量的1.5倍(代码实现:oldCapacity + (oldCapacity >> 1) 严格的说基本上是1.5倍,因为当10->15->22->33,所以15扩容到22的时候不是1.5倍)。在进行容量校验之后会将当前值赋值给数组的size下标元素。

添加元素还重载了add(int index, E element)方法,该方法和上个方法相比,除了多了一个index的校验和要插入的下标后元素的移位复制。

还有addAll(int index, Collection<? extends E> c)和addAll(Collection<? extends E> c) 添加集合元素到该集合,其实现和add(int index, E element),大同小异,只是参数值变大而已。

2.3取出元素

 E get(int index)该方法就是取出对应下标的数组的值,源码实现就是检查下标是否越界,然后就是通过数组下标获取该值。

2.4删除元素

删除元素有两个常用的重载方法:remove(int index)和remove(Object o)。前者是根据下标删除元素后者是删除该对象,只是删除第一次出现的该对象,假如存在的话。根据下标删除就是先校验下标然后判断需要移位的元素,然后将删除的下标数组元素置空,方便GC回收。删除指定对象的方法其实是先找出该对象对应的下表,然后删除逻辑与前者相似。

2.5修改元素

set(int index, E element),该方法是用来修改修改指定下标的元素为新指定的值。其实现是将下标对应的数组的元素替换为新的指定值,并返回原先的值。

3.应用分析

    以上只是分析了可变数组的增删改查以及初始化的源码,其他的一些功能性方法没有做分析。总体上说,可变数组是使我们更加方便的操作数组,增删改查数组中的元素。因为结构决定性状,所以我们从实现上分析使用:

   查询快和修改快,增加和删除慢

    查询和修改只是对指定下标元素进行获取或者重新赋值,所以快;增加元素在扩容的时候需要进行元素复制,删除元素根据下标的不同复制的元素数量不同,如果在元素比较多的情况下扩容或者删除的下标比较靠前,则需要复制的元素会很多,所以慢。因此,在查询多增删少的时候,我们就需要使用这个变长数组了。如果是增删多,查询少那么我们就要使用LinkedList。

猜你喜欢

转载自blog.csdn.net/tony_java_2017/article/details/81184418