ArrayList的源码
来源:互联网 发布:java base64 编辑:程序博客网 时间:2024/06/18 03:47
先看一下ArrayList的使用方法
public class Demo { public static void main(String[] args) { ArrayList<String> list = new ArrayList<String>(); list.add("Item1"); list.add("Item2"); for (int i = 0; i < list.size(); i++) { System.out.println("Index: " + i + " - Item: " + list.get(i)); } }}输出:Index: 0 - Item: Item1Index: 1 - Item: Item2下面我们看一下ArrayList类的属性源码:
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ // 版本号 private static final long serialVersionUID = 8683452581122892189L; // 缺省容量 private static final int DEFAULT_CAPACITY = 10; // 空对象数组 private static final Object[] EMPTY_ELEMENTDATA = {}; // 缺省空对象数组 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // 元素数组 transient Object[] elementData; // 实际元素大小,默认为0 private int size; // 最大数组容量 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;}说明:底层的数据结构就是数组elementData,数组元素类型为Object类型,即可以存放所有类型数据。我们对ArrayList类的实例的所有的操作底层都是基于数组的。ArrayList继承AbstractList抽象父类,实现了List接口(规定了List的操作规范)、RandomAccess(可随机访问)、Cloneable(可拷贝)、Serializable(可序列化)。
下面我们分析三个函数,来了解一下ArrayList的实现,各方法的实现请看源码
1. add函数public boolean add(E e) { ensureCapacityInternal(size + 1); elementData[size++] = e; return true;}说明:在add函数我们发现还有其他的函数ensureCapacityInternal,此函数可以理解为确保elementData数组有合适的大小。ensureCapacityInternal的具体函数如下
private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { // 判断元素数组是否为空数组 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); // 取较大值 } ensureExplicitCapacity(minCapacity);}说明:在ensureCapacityInternal函数中我们又发现了ensureExplicitCapacity函数,这个函数也是为了确保elemenData数组有合适的大小。ensureExplicitCapacity的具体函数如下
private void ensureExplicitCapacity(int minCapacity) { modCount++;// 结构性修改加1 if (minCapacity - elementData.length > 0) grow(minCapacity);}说明:在ensureExplicitCapacity函数我们又发现了grow函数,grow函数才会对数组进行扩容,ensureCapacityInternal、ensureExplicitCapacity都只是过程,最后完成实际扩容操作还是得看grow函数,grow函数的具体函数如下
private void grow(int minCapacity) { int oldCapacity = elementData.length; // 旧容量 int newCapacity = oldCapacity + (oldCapacity >> 1); // 新容量为旧容量的1.5倍 if (newCapacity - minCapacity < 0) // 新容量小于参数指定容量,修改新容量 newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) // 新容量大于最大容量 newCapacity = hugeCapacity(minCapacity); // 指定新容量 // 拷贝扩容 elementData = Arrays.copyOf(elementData, newCapacity);}说明:正常情况下会扩容1.5倍,特殊情况下(新扩展数组大小已经达到了最大值)则只取最大值。
下面看一下如何移除一个元素
public E remove(int index) {// 检查索引是否合法rangeCheck(index);modCount++;E oldValue = elementData(index);// 需要移动的元素的个数int numMoved = size - index - 1;if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index,numMoved);// 赋值为空,有利于进行GCelementData[--size] = null; // 返回旧值return oldValue;}说明:remove函数用户移除指定下标的元素,此时会把指定下标到数组末尾的元素向前移动一个单位,并且会把数组最后一个元素设置为null,这样是为了方便之后将整个数组不被使用时,会被GC
3. get函数
public E get(int index) { // 检验索引是否合法 rangeCheck(index); return elementData(index);}说明:get函数会检查索引值是否合法(只检查是否大于size,而没有检查是否小于0),值得注意的是,在get函数中存在element函数,element函数用于返回具体的元素,具体函数如下
E elementData(int index) { return (E) elementData[index];}说明:返回的值都经过了向下转型(Object -> E),这些是对我们应用程序屏蔽的小细节。
0 0
- ArrayList的源码浅析
- ArrayList的源码分析
- ArrayList的源码
- ArrayList 的源码分析
- ArrayList的源码实现
- Java的ArrayList源码浅析
- ArrayList的迭代器源码分析
- ArrayList简单的源码分析
- 【Java】ArrayList的源码分析
- 【源码解析】-- ArrayList的源码解析
- ArrayList源码
- ArrayList源码
- ArrayList源码
- ArrayList源码
- ArrayList源码
- ArrayList源码
- ArrayList源码
- ArrayList源码
- Boost::Lexical_Cast的使用
- javaweb学习总结(七)——HttpServletResponse对象(一)
- 组合分类器
- android:scaleType 设置图片显示
- Ubuntu Linux 安装 .7z 解压和压缩文件
- ArrayList的源码
- MySQL查询数据表中数据记录(包括多表查询)
- Fiddler On Linux
- ajax动态生成table
- 1.4.1 控件学习-TextView控件学习
- android EditText inputType说明
- 晋升的为什么不是你
- 解决cmd客户端插入包含中文数据乱码
- CentOS6.4系统安装图解