阅读目录- 一、ArrayList简介
- 二、ArrayList源码分析
- 三、ArrayList遍历方式
一、ArrayList简介
ArrayList是可以动态增长和缩减的索引序列,它是基于数组实现的List类。 该类封装了一个动态再分配的Object[]数组,每一个类对象都有一个capacity属性,表示它们所封装的Object[]数组的长度,当向ArrayList中添加元素时,该属性值会自动增加。如果想ArrayList中添加大量元素,可使用ensureCapacity方法一次性增加capacity,可以减少增加重分配的次数提高性能。 ArrayList的用法和Vector向类似,但是Vector是一个较老的集合,具有很多缺点,不建议使用。另外,ArrayList和Vector的区别是:ArrayList是线程不安全的,当多条线程访问同一个ArrayList集合时,程序需要手动保证该集合的同步性,而Vector则是线程安全的。 ArrayList与Collection关系如下图:
二、ArrayList源码分析
下面就ArrayList的源代码进行简单的分析:public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{private static final long serialVersionUID = 8683452581122892189L;//默认的初始容量为10private static final int DEFAULT_CAPACITY = 10;private static final Object[] EMPTY_ELEMENTDATA = {};private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};transient Object[] elementData; // ArrayList中实际数据的数量private int size;public ArrayList(int initialCapacity) //带初始容量大小的构造函数{if (initialCapacity > 0) //初始容量大于0,实例化数组{this.elementData = new Object[initialCapacity];} else if (initialCapacity == 0) //初始化等于0,将空数组赋给elementData{this.elementData = EMPTY_ELEMENTDATA;} else//初始容量小于,抛异常{throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);}}public ArrayList()//无参构造函数,默认容量为10{this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}public ArrayList(Collection<? extends E> c)//创建一个包含collection的ArrayList{elementData = c.toArray(); //返回包含c所有元素的数组if ((size = elementData.length) != 0){if (elementData.getClass() != Object[].class)elementData = Arrays.copyOf(elementData, size, Object[].class);//复制指定数组,使elementData具有指定长度} else{//c中没有元素this.elementData = EMPTY_ELEMENTDATA;}}//将当前容量值设为当前实际元素大小public void trimToSize(){modCount++;if (size < elementData.length) {elementData = (size == 0)? EMPTY_ELEMENTDATA:Arrays.copyOf(elementData, size);}}//将集合的capacit增加minCapacitypublic void ensureCapacity(int minCapacity) {int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)?0:DEFAULT_CAPACITY;if (minCapacity > minExpand){ensureExplicitCapacity(minCapacity);}}private void ensureCapacityInternal(int minCapacity){if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA){minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);}ensureExplicitCapacity(minCapacity);}private void ensureExplicitCapacity(int minCapacity){modCount++;if (minCapacity - elementData.length > 0)grow(minCapacity);}private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;private void grow(int minCapacity){int oldCapacity = elementData.length;
//注意此处扩充capacity的方式是将其向右一位再加上原来的数,实际上是扩充了1.5倍int newCapacity = oldCapacity + (oldCapacity >> 1);if (newCapacity - minCapacity < 0)newCapacity = minCapacity;if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);elementData = Arrays.copyOf(elementData, newCapacity);}private static int hugeCapacity(int minCapacity) {if (minCapacity < 0) // overflowthrow new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}//返回ArrayList的大小public int size(){return size;}//判断ArrayList是否为空public boolean isEmpty() {return size == 0;}//判断ArrayList中是否包含Object(o)public boolean contains(Object o) {return indexOf(o) >= 0;}//正向查找,返回ArrayList中元素Object(o)的索引位置public int indexOf(Object o){if (o == null) {for (int i = 0; i < size; i++)if (elementData[i]==null)return i;} else{for (int i = 0; i < size; i++)if (o.equals(elementData[i]))return i;}return -1;}//逆向查找,返回返回ArrayList中元素Object(o)的索引位置public int lastIndexOf(Object o) {if (o == null) {for (int i = size-1; i >= 0; i--)if (elementData[i]==null)return i;} else {for (int i = size-1; i >= 0; i--)if (o.equals(elementData[i]))return i;}return -1;}//返回此 ArrayList实例的浅拷贝。public Object clone() {try {ArrayList<?> v = (ArrayList<?>) super.clone();v.elementData = Arrays.copyOf(elementData, size);v.modCount = 0;return v;} catch (CloneNotSupportedException e) {// this shouldn"t happen, since we are Cloneablethrow new InternalError(e);}}//返回一个包含ArrayList中所有元素的数组public Object[] toArray() {return Arrays.copyOf(elementData, size);}@SuppressWarnings("unchecked")public <T> T[] toArray(T[] a) {if (a.length < size)return (T[]) Arrays.copyOf(elementData, size, a.getClass());System.arraycopy(elementData, 0, a, 0, size);if (a.length > size)a[size] = null;return a;}@SuppressWarnings("unchecked")E elementData(int index) {return (E) elementData[index];}//返回至指定索引的值public E get(int index) {rangeCheck(index); //检查给定的索引值是否越界return elementData(index);} //将指定索引上的值替换为新值,并返回旧值public E set(int index, E element) {rangeCheck(index);E oldValue = elementData(index);elementData[index] = element;return oldValue;}//将指定的元素添加到此列表的尾部public boolean add(E e) {ensureCapacityInternal(size + 1);elementData[size++] = e;return true;}// 将element添加到ArrayList的指定位置 public void add(int index, E element) {rangeCheckForAdd(index);ensureCapacityInternal(size + 1);//从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。//arraycopy(被复制的数组, 从第几个元素开始复制, 要复制到的数组, 从第几个元素开始粘贴, 一共需要复制的元素个数)//即在数组elementData从index位置开始,复制到index+1位置,共复制size-index个元素System.arraycopy(elementData, index, elementData, index + 1,size - index);elementData[index] = element;size++;}//删除ArrayList指定位置的元素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);elementData[--size] = null; //将原数组最后一个位置置为nullreturn oldValue;}//移除ArrayList中首次出现的指定元素(如果存在)。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;}//快速删除指定位置的元素private void fastRemove(int index){modCount++;int numMoved = size - index - 1;if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index, numMoved);elementData[--size] = null; } //清空ArrayList,将全部的元素设为nullpublic void clear() {modCount++;for (int i = 0; i < size; i++)elementData[i] = null;size = 0;}//按照c的迭代器所返回的元素顺序,将c中的所有元素添加到此列表的尾部public boolean addAll(Collection<? extends E> c) {Object[] a = c.toArray();int numNew = a.length;ensureCapacityInternal(size + numNew);// Increments modCountSystem.arraycopy(a, 0, elementData, size, numNew);size += numNew;return numNew != 0;}//从指定位置index开始,将指定c中的所有元素插入到此列表中public boolean addAll(int index, Collection<? extends E> c) {rangeCheckForAdd(index);Object[] a = c.toArray();int numNew = a.length;ensureCapacityInternal(size + numNew);// Increments modCountint numMoved = size - index;if (numMoved > 0)//先将ArrayList中从index开始的numMoved个元素移动到起始位置为index+numNew的后面去System.arraycopy(elementData, index, elementData, index + numNew, numMoved);//再将c中的numNew个元素复制到起始位置为index的存储空间中去System.arraycopy(a, 0, elementData, index, numNew);size += numNew;return numNew != 0;}//删除fromIndex到toIndex之间的全部元素protected void removeRange(int fromIndex, int toIndex){modCount++;//numMoved为删除索引后面的元素个数int numMoved = size - toIndex;//将删除索引后面的元素复制到以fromIndex为起始位置的存储空间中去System.arraycopy(elementData, toIndex, elementData, fromIndex,numMoved);int newSize = size - (toIndex-fromIndex);//将ArrayList后面(toIndex-fromIndex)个元素置为nullfor (int i = newSize; i < size; i++){elementData[i] = null;}size = newSize;}//检查索引是否越界private void rangeCheck(int index){if (index >= size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}private void rangeCheckForAdd(int index) {if (index > size || index < 0)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}private String outOfBoundsMsg(int index) {return "Index: "+index+", Size: "+size;}//删除ArrayList中包含在c中的元素public boolean removeAll(Collection<?> c){Objects.requireNonNull(c);return batchRemove(c, false);}//删除ArrayList中除包含在c中的元素,和removeAll相反public boolean retainAll(Collection<?> c) {Objects.requireNonNull(c);//检查指定对象是否为空return batchRemove(c, true);}private boolean batchRemove(Collection<?> c, boolean complement) {final Object[] elementData = this.elementData;int r = 0, w = 0;boolean modified = false;try {for (; r < size; r++)if (c.contains(elementData[r]) == complement)//判断c中是否有elementData[r]元素elementData[w++] = elementData[r];}finally {if (r != size) {System.arraycopy(elementData, r, elementData, w, size - r);w += size - r;}if (w != size) {// clear to let GC do its workfor (int i = w; i < size; i++)elementData[i] = null;modCount += size - w;size = w;modified = true;}}return modified;}//将ArrayList的“容量,所有的元素值”都写入到输出流中 private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{int expectedModCount = modCount;s.defaultWriteObject();//写入数组大小s.writeInt(size);//写入所有数组的元素for (int i=0; i<size; i++) {s.writeObject(elementData[i]);}if (modCount != expectedModCount) {throw new ConcurrentModificationException();}}//先将ArrayList的“大小”读出,然后将“所有的元素值”读出private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {elementData = EMPTY_ELEMENTDATA;s.defaultReadObject();s.readInt(); // ignoredif (size > 0) {// be like clone(), allocate array based upon size not capacityensureCapacityInternal(size);Object[] a = elementData;// Read in all elements in the proper order.for (int i=0; i<size; i++) {a[i] = s.readObject();}}}
三、ArrayList遍历方式
ArrayList支持3种遍历方式 1、通过迭代器遍历:Iterator iter = list.iterator();while (iter.hasNext()){System.out.println(iter.next());} 2、随机访问,通过索引值去遍历,由于ArrayList实现了RandomAccess接口int size = list.size();for (int i=0; i<size; i++) {System.out.println(list.get(i));} 3、for循环遍历:for(String str:list){System.out.println(str); } 完整的代码示例如下:public class DemoMain {public static void main(String[] args){List<String> list=new ArrayList<String>();list.add("nihao");list.add("xujian");list.add("wang");System.out.println("--------通过迭代器遍历---------");Iterator iter = list.iterator();while (iter.hasNext()){ System.out.println(iter.next());}System.out.println("--------通过随机访问---------");int size = list.size();for (int i=0; i<size; i++) {System.out.println(list.get(i));}System.out.println("--------通过for循环访问---------");for(String str:list){System.out.println(str);}}} 运行结果如图示:
本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-07/120217.htm