ArrayList源码分析篇

  • 内容
  • 评论
  • 相关

之前了解分析过HashMap的源码,今天看看ArrayList源码,希望对大家有帮助,共同学习,共同进步。

 

ArrayList简介

ArrayList继承AbstractList,实现List,RandomAccess,Cloneable,Serializable。

 

继承结构图如下:

 

ArrayList是一个动态数组的实现方式,提供对元素的crud操作,ArrayList使我们在开发过程中经常使用的一个数据结构。

 

预期并论的还得说说LinkedList,其底层实现是链表,具体使用就看使用场景了。因为ArrayList底层是数组,所以查找,修改性能稍好,而LinkedList底层是链表的数据结构,所以增删性能稍后。性能的好坏数据量越大,性能越明显。

 

常用操作

 

从上面的常用操作来看,在日常开发过程中有:构造、addgetsizeiteratorcontainsindexOflastIndexOfset等方法,接下来还是依照日常操作去理解源码和分析源码。

 

在看方法之前,先了解一下ArrayList的一些成员变量:

 

DEFAULT_CAPACITY:默认的初始化容量。

EMPTY_ELEMENTDATA:始终为一个空Object数组。

源码注释:

/**

* Shared empty array instance used for empty instances.

*/

DEFAULTCAPACITY_EMPTY_ELEMENTDATA:始终为一个空Object数组。

源码注释:

/**

* Shared empty array instance used for default sized empty instances. We

* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when

* first element is added.

*/

elementData:最终存储元素的数组。

size:集合的大小。

MAX_ARRAY_SIZE:集合最大数量,这里的最大是Integer.MAX_VALUE-8,至于为什么要减8,注释给的说明是有些VM在数组中保留一些标题字。

 

构造方法

ArrayList有三个,分别是ArrayList(),ArrayList(int),ArrayList(Collection<? extends E>)。其实只要是Collection或Map下的实现类一般情况都有这三个构造方法。如HashMap、HashTable、ConcurrentHashMap、ArrayList、LinkedList(2个)、Vector、HashSet、TreeSet ......

 

ArrayList():

 

ArrayList(int):

 

ArrayList(Collection<? extends E>):

 

通过这三段代码,应该不能看出什么,但是我建议:如果能确定该集合的大小,尽量指定大小。

 

add方法

通过查看add方法,ArrayList内部有两个add方法,一个是add(E e),另一个是add(int index, E element)。

 

 

从add(E e)方法来看,如果超出大小则会进行扩容,而扩容机制为: int newCapacity = oldCapacity + (oldCapacity >> 1);

这个扩容机制也就是说,X = X + X / 2 (X为集合的大小)

为什么选择1.5倍?而不是2.0、2.5之类的?

据说是选择1.5正好,为什么正好?过大会浪费空间,过小会扩容频繁导致性能下降,所以选择1.5正好。

 

 

从add(int index, E element)方法来看,在集合的第index位置插入元素,而调用此方法,需要进行数组的copy。如果插入的位置非常靠前,且集合数据过大,则性能会非常低下,如果这种操作很频繁,建议使用LinkedList。这也就说明了如果插入元素过于频繁,可能会不断扩容或不断移动数据的位置,删除也是同样的道理,所以如果对集合增删操作很频繁的话,不建议使用ArrayList,建议使用LinkedList。

 

size方法

list.size()方法返回的是当前集合有效元素的个数。

因为在每一次操作,都会改变size的大小,所以直接返回成员变量size即可。

 

get方法

get方法是我们最常用的方法之一,是获取元素的途径。方法过于简单,没必要过多叙述。

 

remove方法

remove方法提供集合对元素的删除操作,其中包括remove(int index)、remove(Object o)、fastRemove(int index)、clear()

 

remove(int index):移除index位置的元素

 

remove(Object o):remove符合条件的第一个元素

 

fastRemove(int index):内部快速移除元素并移动index后的元素

 

clear():

 

跟remove相关的还有removeAll(Collection<?> c)、batchRemove(Collection<?> c, boolean complement)等等。

 

contains方法

contains也是日常开发常用方法之一,其功能是判断某元素是否存在于集合。

 

 

直接调用了indexOf()方法,如果返回值>=0说明存在,否则不存在,接下来看看indexOf方法。

 

indexOf方法

indexOf,从集合中找到与传入元素相等的第一次出现元素,返回其下标,若没找到,则返回-1。

 

其实就是遍历然后equals,找到返回下标。

 

两个方法一对比,indexOf是从头到尾遍历从而找到第一个,lastIndexOf是从尾到头从而找到最后一个。

 

set方法

Object oldValue = list.set(3, "");

 

 

拓展------Java8的的支持

 

 

 

 

 

 

 

 

 

 

 

认定了路,无论怎么难走,都要坚持下去。

喜欢 4

评论

0条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Title - Artist
0:00