JDK源码浅析之ArrayList类
2016-05-01 14:36
447 查看
以下解析基于JDK8.0
ArrayList的继承关系如下:
比如说ArrayList mylist = new ArrayList(); mylist.add(new Object());在这种情况下,第一次add一个元素,则mylist的容量扩展为10(上面这个默认初始化大小为10貌似容易引起误会,以为是ArrayList对象刚new出来容量就初始化为10了,其实并没有。不过在初始化ArrayList的时候确实可以调用一个带参数的构造函数以指定初始化的容量:如ArrayList mylist = new ArrayList(20);这样的话对象一new出来容量就为20了,两个构造函数如下:)
ArrayList的扩容机制是每次增长为原容量的1.5倍,具体代码如下:
再来看一下remove方法:
ArrayList中还包含很多其他的方法,在这里就不一一列举了。水平有限,如有不当之处,还望指正!
ArrayList的继承关系如下:
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {ArrayList的底层是用数组实现的:
transient Object[] elementData; // non-private to simplify nested class accessArrayList的默认初始化大小是10:
/** * Default initial capacity. */ private static final int DEFAULT_CAPACITY = 10;
比如说ArrayList mylist = new ArrayList(); mylist.add(new Object());在这种情况下,第一次add一个元素,则mylist的容量扩展为10(上面这个默认初始化大小为10貌似容易引起误会,以为是ArrayList对象刚new出来容量就初始化为10了,其实并没有。不过在初始化ArrayList的时候确实可以调用一个带参数的构造函数以指定初始化的容量:如ArrayList mylist = new ArrayList(20);这样的话对象一new出来容量就为20了,两个构造函数如下:)
public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }
public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }上面出现的两个常量如下所示:
/** * Shared empty array instance used for empty instances. */ private static final Object[] EMPTY_ELEMENTDATA = {}; /** * 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. */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};两个常量都是static final类型的空数组,之所以要有第二个常量DEFAULTCAPACITY_EMPTY_ELEMENTDATA是为了能够在第一次add元素需要进行扩容的时候判断是否将容量扩充为默认初始化容量10(如果这个容量足够的话)。上面代码中的注释说的就是这个意思。我们可以看一下add方法的代码:
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); }
ArrayList的扩容机制是每次增长为原容量的1.5倍,具体代码如下:
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }从代码中可以看出,如果一次扩容还达不到minCapacity的时候则新容量直接赋值为minCapacity(所以扩容的增长路线并不一定是10,15,22……这样增长的,而且初始化的时候也还可以指定容量),同时从上述代码最后一行也可以看出来,所谓的扩容就是把数组元素复制到一个更大空间的数组中。
再来看一下remove方法:
public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; }注意到在查找要删除的元素时采用的是equals方法,因此添加到ArrayList中的元素所属的类(尤其是我们自定义的类)最好需要重写一下equals方法,否则得到的结果可能并不是你想要的。从上面代码我们还能看出来的一点是ArrayList里面可以包含null元素,为了避免出现空指针异常,上面的代码分别处理了元素为null以及不为null的情况。
ArrayList中还包含很多其他的方法,在这里就不一一列举了。水平有限,如有不当之处,还望指正!
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树