ArrayList应该知道的那些事(基于JDK1.8)
初识集合种类
相信学习过的java的同学对 ArrayList 这个词并不陌生。没错这是集合中的一个类型,常见的还有Vector、LinkedList、HashMap、HashTable、HashTree等等,不过今天我们的重点是ArrayList,它的兄弟姐妹们暂且不提。首先让我们通过一张图来了解下集合框架的情况
ArrayList介绍
ArrayList是一个数组队列,是一个动态数组,可以通过扩容的方式来改变它的默认容量长度。
- 数据结构继承关系
上面的图话的不是很清楚,那我们通过源码中的代码来看下结构
以及继承关系结构图:
通过上面的图我们就能对ArrayList有一个总结性的概述了。
①它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口。
②ArrayList 继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
③ArrayList实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。
④ ArrayList 实现了Cloneable接口,即覆盖了函数clone(),能被克隆。
⑤ArrayList 实现java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。
常见API
size:返回集合的大小
isEmpty:判断集合是否为空
contains:集合中是否包含某个元素
toArray:得到array结果的集合数据类型
add:往集合中添加元素,改变集合的大小和内容信息
remove:移除某个集合中的某个元素
clear:清空该集合中的所有元素信息
源码剖析(JDK1.8)
1.构造方法
在ArrayList中有三个构造方法,如下所示:
- 无参构造,默认容量长度为10
- capacity是ArrayList的默认容量大小(10)。当由于增加数据导致容量不足时,容量会添加上一次容量大小的一半
- 创建一个包含collection的ArrayList
- 关于扩容
谈到扩容这个话题,就不得不说add()这个方法了,老规矩,先看代码:
上面就是add方法的源码,虽然方法里面的代码只有短短的3行,用成语形容就是短小精悍,言简意赅,咳咳咳,跑偏了啊,回到我们的代码来。
首先我们看下第一行ensureCapacityInternal(size + 1),苍天啊,大地啊,一来就是调用方法的嘛?一开始就调用了一个方法,该方法中并且有一个属性值size。
add方法执行的核心代码如下:
1)确保数组已使用长度(size)加1之后足够存下 下一个数据
ensureCapacityInternal(size + 1);
2)
修改次数modCount 标识自增1
modCount++
,
如果当前数组已使用长度(size)加1后的大于当前的数组长度
if (minCapacity - elementData.length > 0)
,则调用grow方法,增长数组,grow方法会将当前数组的长度变为原来容量的1.5(oldCapacity + (oldCapacity >> 1))倍。
int newCapacity = oldCapacity + (oldCapacity >> 1)
3)确保新增的数据有地方存储之后,则将新元素添加到位于size的位置上
elementData[size++] = e;
。
4)最后回到了add方法中的最后一行
return true;
好了,现在我们的对add方法扩容的实际容量有了一个大致的了解,当数据长度不够的话扩容为原来容量的1.5倍,这点让我想到了StringBuilder的扩容,它的扩容是原来的2倍+2的大小,关于扩容就到这里了
ArrayList常见的遍历方式
这三者遍历结果的效率有所不同,在此就不继续阐述了,希望大家有时间的话就去了解下吧!
写在最后,这是隔了很久以后才写的博客了,突然发现其实写博客也是一个很好的学习方式,不管怎么样,至少是对自己学习成果的一个肯定吧。