android中ArrayList源码分析
来源:互联网 发布:深蓝知乎 编辑:程序博客网 时间:2024/06/06 01:01
ArrayList是继承AbstractList,并实现了Cloneable,Serializable,RandomAccess接口。
不明白AbstractList,和Cloneable,Serializable,RandomAccess接口的请查看以下博客内容。
关于Cloneable ,Serializable接口请参看
http://kentkwan.iteye.com/blog/739514
关于请参看我的另一张博客:
http://blog.csdn.net/bibi_love2008/article/details/52669646
RandomAccess接口:
https://my.oschina.net/u/1466553/blog/496024。
准备工作做好之后,我们先上源码,在源码中我以注释的方式,来表达我的理解。
public class ArrayList<E> extends AbstractList<E> implements Cloneable, Serializable, RandomAccess { /** * The minimum amount by which the capacity of an ArrayList will increase. * This tuning parameter controls a time-space tradeoff. This value (12) * gives empirically good results and is arguably consistent with the * RI's specified default initial capacity of 10: instead of 10, we start * with 0 (sans allocation) and jump to 12. */ private static final int MIN_CAPACITY_INCREMENT = 12;//当空间不够时,默认最小增长12个数组 /** * The number of elements in this list. */ int size;//集合中元素的个数 /** * The elements in this list, followed by nulls. */ transient Object[] array;//Arraylist底层是由数组形式实现的 /** * Constructs a new instance of {@code ArrayList} with the specified * initial capacity. * * @param capacity * the initial capacity of this {@code ArrayList}. */ public ArrayList(int capacity) { //构造方法,capacity代表初始化数组的大小 if (capacity < 0) {//当capacity <0时,则抛出IllegalArgumentException throw new IllegalArgumentException("capacity < 0: " + capacity); }//三元运算符,当capacity =0时,EmptyArray.OBJECT,当capacity>0,时则new Object数组,数组大小是 capacity } /** * Constructs a new {@code ArrayList} instance with zero initial capacity. */ public ArrayList() { //无参构造方法。将EmptyArray.OBJECT赋值给array ,EmptyArray.OBJECT 是Object []obj=new Object[0]; array = EmptyArray.OBJECT; } /** * Constructs a new instance of {@code ArrayList} containing the elements of * the specified collection. * * @param collection * the collection of elements to add. */ public ArrayList(Collection<? extends E> collection) {//构造函数,参数为Collection集合 if (collection == null) {//当collection =null时,会抛出NullPointerException异常。 throw new NullPointerException("collection == null"); } Object[] a = collection.toArray();//将collection集合转换成Object数组//判断一下数据类型是不是Object[]类型,(说明一下: Object[] a = //new Object[3];和Integer[] b = new Integer[3];他们两个的类型是不相等的),//如果不是Object[]类型,则新创建一个长度为a.length的Object数组,//并把数组拷贝到新的Object数组,把新的数组赋值给a Object[] newArray = new Object[a.length]; System.arraycopy(a, 0, newArray, 0, a.length); a = newArray; } array = a;//将a数组赋值给array size = a.length;//元素个数为a.length } /** * Adds the specified object at the end of this {@code ArrayList}. * * @param object * the object to add. * @return always true */ @Override public boolean add(E object) {//向arrayList中添加元素, Object[] a = array;//先将array赋值给一个临时的环境变量a int s = size;//计入当前添加ArrayList中的元素的个数 if (s == a.length) { //判断当前容器是否已经满了,如果满了,就需要扩容。扩容规则:当前容器小于MIN_CAPACITY_INCREMENT / 2时,则增加个MIN_CAPACITY_INCREMENT个,否则增加s/2个空间。,(说明:左移运算符,num << 1,相当于num乘以2,右移运算符,num >> 1,相当于num除以2),并将旧的数据拷贝到新的数组。并赋值给array. Object[] newArray = new Object[s + (s < (MIN_CAPACITY_INCREMENT / 2) ? MIN_CAPACITY_INCREMENT : s >> 1)]; System.arraycopy(a, 0, newArray, 0, s); array = a = newArray; } a[s] = object; size = s + 1; modCount++; return true; } /** * Inserts the specified object into this {@code ArrayList} at the specified * location. The object is inserted before any previous element at the * specified location. If the location is equal to the size of this * {@code ArrayList}, the object is added at the end. * * @param index * the index at which to insert the object. * @param object * the object to add. * @throws IndexOutOfBoundsException * when {@code location < 0 || location > size()} */ @Override public void add(int index, E object) {//添加元素到指定位置 Object[] a = array; int s = size; if (index > s || index < 0) {//当index大于容器大小时,或index<0时则抛出IndexOutOfBoundException throwIndexOutOfBoundsException(index, s); } if (s < a.length) {//当容器空间够用时,通过数组coppy方式移动数组 System.arraycopy(a, index, a, index + 1, s - index); } else {//当容器空间不够用时,创建新的数组,并将数据拷贝到新的数组中。并在新的数组中移动位置 // assert s == a.length; Object[] newArray = new Object[newCapacity(s)]; System.arraycopy(a, 0, newArray, 0, index); System.arraycopy(a, index, newArray, index + 1, s - index); array = a = newArray; } a[index] = object; size = s + 1; modCount++; } /** * This method controls the growth of ArrayList capacities. It represents * a time-space tradeoff: we don't want to grow lists too frequently * (which wastes time and fragments storage), but we don't want to waste * too much space in unused excess capacity. * * NOTE: This method is inlined into {@link #add(Object)} for performance. * If you change the method, change it there too! */ private static int newCapacity(int currentCapacity) {//扩容规则:当前容器小于MIN_CAPACITY_INCREMENT / 2时,则增加个MIN_CAPACITY_INCREMENT个,否则增加s/2个空间。, //(说明:左移运算符,num << 1,相当于num乘以2,右移运算符,num >> 1,相当于num除以2) int increment = (currentCapacity < (MIN_CAPACITY_INCREMENT / 2) ? MIN_CAPACITY_INCREMENT : currentCapacity >> 1); return currentCapacity + increment; } /** * Adds the objects in the specified collection to this {@code ArrayList}. * * @param collection * the collection of objects. * @return {@code true} if this {@code ArrayList} is modified, {@code false} * otherwise. */ @Override public boolean addAll(Collection<? extends E> collection) {//添加一个集合到容器中,返回值为boolean类型,添加成功为true,失败为false Object[] newPart = collection.toArray();//先将collection转化为数组 int newPartSize = newPart.length;//获取数组长度 if (newPartSize == 0) {//如果collection集合为空则添加失败。 return false; } Object[] a = array;//创建一个局部变量,将当前容器中的array赋值给a。 int s = size;//获取当前容器中的大小 int newSize = s + newPartSize; //计算出添加之后所需要的容器大小 if (newSize > a.length) {//当新增加之后的容器大小,大于原有容的大小时则进行扩容。扩容规则请看newCapacity注释 int newCapacity = newCapacity(newSize - 1); // ~33% growth room Object[] newArray = new Object[newCapacity]; System.arraycopy(a, 0, newArray, 0, s); array = a = newArray; } System.arraycopy(newPart, 0, a, s, newPartSize); size = newSize; modCount++; return true; } /** * Inserts the objects in the specified collection at the specified location * in this List. The objects are added in the order they are returned from * the collection's iterator. * * @param index * the index at which to insert. * @param collection * the collection of objects. * @return {@code true} if this {@code ArrayList} is modified, {@code false} * otherwise. * @throws IndexOutOfBoundsException * when {@code location < 0 || location > size()} */ @Override public boolean addAll(int index, Collection<? extends E> collection) {//将集合插入到容器中指定的位置。返回类型boolean值,true为添加成功,false为添加失败。 int s = size; if (index > s || index < 0) {//当index<0或者index大约当前容器长度则抛出IndexOutOfBoundsException异常 throwIndexOutOfBoundsException(index, s); } Object[] newPart = collection.toArray();//将传入的collection参数转换成Object数组。 int newPartSize = newPart.length;获取传入集合的长度 if (newPartSize == 0) {//当传入集合为空时,则返回false return false; } Object[] a = array;//原理与addAll方式一样,不在这里过多注释 int newSize = s + newPartSize; // If add overflows, arraycopy will fail if (newSize <= a.length) { System.arraycopy(a, index, a, index + newPartSize, s - index); } else { int newCapacity = newCapacity(newSize - 1); // ~33% growth room Object[] newArray = new Object[newCapacity]; System.arraycopy(a, 0, newArray, 0, index); System.arraycopy(a, index, newArray, index + newPartSize, s-index); array = a = newArray; } System.arraycopy(newPart, 0, a, index, newPartSize); size = newSize; modCount++; return true; } /** * This method was extracted to encourage VM to inline callers. * TODO: when we have a VM that can actually inline, move the test in here too! */ static IndexOutOfBoundsException throwIndexOutOfBoundsException(int index, int size) { throw new IndexOutOfBoundsException("Invalid index " + index + ", size is " + size); } /** 清空容器,将容器中数组中的对象都设置为null.具有以下功能:1、 给数组赋值:通过fill方法。2、对数组排序:通过sort方法,按升序。3、比较数组:通过equals方法比较数组中元素值是否相等。4、查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。) */ @Override public void clear() { if (size != 0) { Arrays.fill(array, 0, size, null); size = 0; modCount++; } } /** 复制,ArrayList实现了Cloneable接口,clone方法的作用。这个复制函数返回的是一个新对象而不是一个引用。使用clone方法需要实现clone的类继承Cloneable接口。(Cloneable接口是一个标识接口。),在类中重写clone方法,在clone方法中调用super.clone(),无论clone类的继承结构是什么,super.clone()都会直接的或者间接的调用java.lang.Object类中的clone()方法。把浅复制的引用指向原型中的克隆体。(浅复制:被复制的对象的所有变量都含有与原来对象相同的值,而所有对其它对象的引用仍然指向原来的对象。换言之,浅复制对象仅仅复制的考虑的对象,而不复制它所引用的对象。 深复制:被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其它对象的变量。那些引用其它对象的变量将指向被复制的新对象,而不再是原有的那些被引用的对象) */ @Override public Object clone() {// try { ArrayList<?> result = (ArrayList<?>) super.clone(); result.array = array.clone(); return result; } catch (CloneNotSupportedException e) { throw new AssertionError(); } } /** * Ensures that after this operation the {@code ArrayList} can hold the * specified number of elements without further growing. * * @param minimumCapacity * the minimum capacity asked for. */ public void ensureCapacity(int minimumCapacity) { Object[] a = array; if (a.length < minimumCapacity) { Object[] newArray = new Object[minimumCapacity]; System.arraycopy(a, 0, newArray, 0, size); array = newArray; modCount++; } } @SuppressWarnings("unchecked") @Override public E get(int index) { if (index >= size) { throwIndexOutOfBoundsException(index, size); } return (E) array[index]; } /** * Returns the number of elements in this {@code ArrayList}. * * @return the number of elements in this {@code ArrayList}. */ @Override public int size() { return size; } @Override public boolean isEmpty() { return size == 0; } /** * Searches this {@code ArrayList} for the specified object. * * @param object * the object to search for. * @return {@code true} if {@code object} is an element of this * {@code ArrayList}, {@code false} otherwise */ @Override public boolean contains(Object object) { Object[] a = array; int s = size; if (object != null) { for (int i = 0; i < s; i++) { if (object.equals(a[i])) { return true; } } } else { for (int i = 0; i < s; i++) { if (a[i] == null) { return true; } } } return false; } @Override public int indexOf(Object object) { Object[] a = array; int s = size; if (object != null) { for (int i = 0; i < s; i++) { if (object.equals(a[i])) { return i; } } } else { for (int i = 0; i < s; i++) { if (a[i] == null) { return i; } } } return -1; }/*** 重写了AbstractList中的lastIndexOf方法,在AbstractList中lastIndex方法利用了迭代器FullListIterator实现了这个方法。 而在ArrayList中却直接遍历数组,没有沿用父类的方法。 体现了java中的多态*/ @Override public int lastIndexOf(Object object) {// Object[] a = array; if (object != null) { for (int i = size - 1; i >= 0; i--) { if (object.equals(a[i])) { return i; } } } else { for (int i = size - 1; i >= 0; i--) { if (a[i] == null) { return i; } } } return -1; } /** * Removes the object at the specified location from this list. * * @param index * the index of the object to remove. * @return the removed object. * @throws IndexOutOfBoundsException * when {@code location < 0 || location >= size()} */ @Override public E remove(int index) { Object[] a = array; int s = size; if (index >= s) { throwIndexOutOfBoundsException(index, s); } @SuppressWarnings("unchecked") E result = (E) a[index]; System.arraycopy(a, index + 1, a, index, --s - index); a[s] = null; // Prevent memory leak size = s; modCount++; return result; } @Override public boolean remove(Object object) { Object[] a = array; int s = size; if (object != null) { for (int i = 0; i < s; i++) { if (object.equals(a[i])) { System.arraycopy(a, i + 1, a, i, --s - i); a[s] = null; // Prevent memory leak size = s; modCount++; return true; } } } else { for (int i = 0; i < s; i++) { if (a[i] == null) { System.arraycopy(a, i + 1, a, i, --s - i); a[s] = null; // Prevent memory leak size = s; modCount++; return true; } } } return false; } @Override protected void removeRange(int fromIndex, int toIndex) { if (fromIndex == toIndex) { return; } Object[] a = array; int s = size; if (fromIndex >= s) { throw new IndexOutOfBoundsException("fromIndex " + fromIndex + " >= size " + size); } if (toIndex > s) { throw new IndexOutOfBoundsException("toIndex " + toIndex + " > size " + size); } if (fromIndex > toIndex) { throw new IndexOutOfBoundsException("fromIndex " + fromIndex + " > toIndex " + toIndex); } System.arraycopy(a, toIndex, a, fromIndex, s - toIndex); int rangeSize = toIndex - fromIndex; Arrays.fill(a, s - rangeSize, s, null); size = s - rangeSize; modCount++; } /** * Replaces the element at the specified location in this {@code ArrayList} * with the specified object. * * @param index * the index at which to put the specified object. * @param object * the object to add. * @return the previous element at the index. * @throws IndexOutOfBoundsException * when {@code location < 0 || location >= size()} */ @Override public E set(int index, E object) {//更新坐标为index的元素内容为object Object[] a = array; if (index >= size) { throwIndexOutOfBoundsException(index, size); } @SuppressWarnings("unchecked") E result = (E) a[index]; a[index] = object; return result; } /** * Returns a new array containing all elements contained in this * {@code ArrayList}. * * @return an array of the elements from this {@code ArrayList} */ @Override public Object[] toArray() { int s = size; Object[] result = new Object[s]; System.arraycopy(array, 0, result, 0, s); return result; } /** T是代表任意一种类型,这是泛型里的问题,<T>是一种形式,表示你用的是泛型编程,不受类型的约束 */ @Override public <T> T[] toArray(T[] contents) { int s = size; if (contents.length < s) { @SuppressWarnings("unchecked") T[] newArray = (T[]) Array.newInstance(contents.getClass().getComponentType(), s); contents = newArray; } System.arraycopy(this.array, 0, contents, 0, s); if (contents.length > s) { contents[s] = null; } return contents; } /** * Sets the capacity of this {@code ArrayList} to be the same as the current * size. * * @see #size */ public void trimToSize() {//整理容器空间,我们从clear方法中看到我们只是将数组中的元素设置为null,但是数组占用的空间并没有进行设置。我理解为ArrayList为了复用ArrayList,避免过多的创建内存空间,所以在clear的时候,并没有更改底层array的大小。于是提供了trimToSize. int s = size; if (s == array.length) {//当前元素个数等于容器大小,则什么也不做。直接return return; } if (s == 0) {//当size=0时。将容器设置为长度为0的属猪 array = EmptyArray.OBJECT; } else {//否则创建一个新的大小为当前size的数组。 Object[] newArray = new Object[s]; System.arraycopy(array, 0, newArray, 0, s); array = newArray; } modCount++; } @Override public Iterator<E> iterator() {//迭代遍历器 return new ArrayListIterator(); } private class ArrayListIterator implements Iterator<E> { /** Number of elements remaining in this iteration */ private int remaining = size;//当前容器中的大小 /** Index of element that remove() would remove, or -1 if no such elt */ private int removalIndex = -1;//删除的坐标 /** The expected modCount value */ private int expectedModCount = modCount; public boolean hasNext() { return remaining != 0; } @SuppressWarnings("unchecked") public E next() { ArrayList<E> ourList = ArrayList.this; int rem = remaining; if (ourList.modCount != expectedModCount) { throw new ConcurrentModificationException(); } if (rem == 0) { throw new NoSuchElementException(); } remaining = rem - 1; return (E) ourList.array[removalIndex = ourList.size - rem]; } public void remove() { Object[] a = array; int removalIdx = removalIndex; if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } if (removalIdx < 0) { throw new IllegalStateException(); } System.arraycopy(a, removalIdx + 1, a, removalIdx, remaining); a[--size] = null; // Prevent memory leak removalIndex = -1; expectedModCount = ++modCount; } } @Override public int hashCode() { Object[] a = array; int hashCode = 1; for (int i = 0, s = size; i < s; i++) { Object e = a[i]; hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode()); } return hashCode; } @Override public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof List)) { return false; } List<?> that = (List<?>) o; int s = size; if (that.size() != s) { return false; } Object[] a = array; if (that instanceof RandomAccess) { for (int i = 0; i < s; i++) { Object eThis = a[i]; Object ethat = that.get(i); if (eThis == null ? ethat != null : !eThis.equals(ethat)) { return false; } } } else { // Argument list is not random access; use its iterator Iterator<?> it = that.iterator(); for (int i = 0; i < s; i++) { Object eThis = a[i]; Object eThat = it.next(); if (eThis == null ? eThat != null : !eThis.equals(eThat)) { return false; } } } return true; } private static final long serialVersionUID = 8683452581122892189L; private void writeObject(ObjectOutputStream stream) throws IOException {//序列化 stream.defaultWriteObject(); stream.writeInt(array.length); for (int i = 0; i < size; i++) { stream.writeObject(array[i]); } } private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {//反序列化 stream.defaultReadObject(); int cap = stream.readInt(); if (cap < size) { throw new InvalidObjectException( "Capacity: " + cap + " < size: " + size); } array = (cap == 0 ? EmptyArray.OBJECT : new Object[cap]); for (int i = 0; i < size; i++) { array[i] = stream.readObject(); } } }
在我的android 环境中找不到这个EmptyArray 源码,现在从网络上找到源码,源码如下:
package libcore.util;public final class EmptyArray { private EmptyArray() {} public static final boolean[] BOOLEAN = new boolean[0]; public static final byte[] BYTE = new byte[0]; public static final char[] CHAR = new char[0]; public static final double[] DOUBLE = new double[0]; public static final int[] INT = new int[0]; public static final Class<?>[] CLASS = new Class[0]; public static final Object[] OBJECT = new Object[0]; public static final String[] STRING = new String[0]; public static final Throwable[] THROWABLE = new Throwable[0]; public static final StackTraceElement[] STACK_TRACE_ELEMENT = new StackTraceElement[0];}
总结:线性表的顺序存储结构,也称为顺序表,指用一段连续的存储单元依次存储线性表中的数据元素。
根据顺序表的特性,我们用数组来实现顺序表,ArrayList实现了线性表中的顺序表。
0 0
- android中ArrayList源码分析
- JDK8中ArrayList源码分析
- ArrayList源码分析(Java&Android)
- ArrayList源码分析
- ArrayList源码分析
- ArrayList 源码分析
- ArrayList源码分析
- ArrayList LinkedList 源码分析
- ArrayList,LinkedList源码分析
- 源码分析之ArrayList
- ArrayList 源码分析
- ArrayList源码分析
- ArrayList源码分析
- ArrayList源码分析
- ArrayList源码分析
- ArrayList源码分析
- ArrayList 源码分析
- Java ArrayList源码分析
- 死锁
- 72. Edit Distance
- 226. Invert Binary Tree
- 你不知道的Java学习笔记15--StringBuffer类
- Lucene学习教程——Lucene索引创建
- android中ArrayList源码分析
- mysql5.5全备份的问题(- Warning: Skipping the data of table mysql.event. Specify the --events option expli)
- CODEVS 2072 分配房间
- spark如何划分stage
- centos下安装git
- Android属性动画(二)——ValueAnimator
- Git安装与基本操作总结
- Jquery datatable 页面报错 Ajax error
- Java基础学习总结(64)——Java内存管理