java_集合体系之ArrayList详解、源码及示例――03

2014-11-24 07:42:53 · 作者: · 浏览: 0

java_集合体系之ArrayList详解、源码及示例――03


一:ArrayList结构图


\

< http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+vPK1pcu1w/ejujwvcD4KPHA+MaGiyc/NvNbQ0OnP38fSzt7SwMC119bR+aGiy7XD98rH1rG908q1z9a1xL3Tv9o8L3A+CjxwPjKhotDpz9+1q8rH09DSwMC119bR+aGiy7XD97TLwODSwMC10+u907/aoaK1q7K7ysfWsb3TyrXP1r3Tv9o8L3A+CjxwPjOhosq1z9/Kx7zMs9C52M+1oaLA4LzMs9DA4KGivdO/2rzMs9C907/aPC9wPgo8cD4gPC9wPgo8aDI+tv6jukFycmF5TGlzdMDgvPK96aO6PC9oMj4KPGJyPgoKPHA+ICAgICAgICAgICAgMaGiQXJyYXlMaXN0ysfE2rK/ysfS1LavzKzK/dfptcTQzsq9wLS05rSiyv2+3bXEoaLWqrXAyv3X6bXEv8nE3Lvh0sm786O6yv3X6bK7yse2qLOktcTC8KO/1eLA77XEtq/MrMr91+myu8rH0uLOttfFyKW4xLHk1K3T0MTasr/J+rPJtcTK/dfptcSzpLbIoaK2+MrHsaPB9NSt09DK/dfptcTS/dPDoaK9q8bk1rjP8tDCyfqzybXEyv3X6bbUz/OhotXi0fm74dTss8nK/dfptcSzpLbIv8mx5LXEvNnP86GjPC9wPgo8cD4gICAgICAgICAgICAyoaJBcnJheUxpc3S+39PQyv3X6cv5vt/T0LXEzNjQ1KGizai5/cv30v3Wp7PWy+a7+rfDzsqhosv50tTNqLn9y+a7+rfDzspBcnJheUxpc3TW0LXE1KrL2NCnwsq3x7OjuN+horWrysfWtNDQsuXI66Giyb6z/cqx0KfCyrHIvc+12M/CoaK+38zl1K3S8rrzw+bT0LfWzvahozwvcD4KPHA+ICAgICAgICAgICAgM6GiQXJyYXlMaXN0yrXP1sHLQWJzdHJhY3RMaXN0s+nP88DgoaJMaXN0vdO/2qGiy/nS1MbkuPy+39PQwctBYnN0cmFjdExpc3S6zUxpc3S1xLmmxNyhoseww+bO0sPH1qq1wEFic3RyYWN0TGlzdMTasr/S0b6tyrXP1sHLu/HIoUl0ZXJhdG9yus1MaXN0SXRlcmF0b3K1xLe9t6ihosv50tRBcnJheUxpc3TWu9DoudjQxLbUyv3X6bLZ1/e1xLe9t6i1xMq1z9ahojwvcD4KPHA+ICAgICAgICAgICAgNKGiQXJyYXlMaXN0yrXP1sHLUmFuZG9tQWNjZXNzvdO/2qGitMu907/a1rvT0Mn5w/ehosO709C3vbeozOWhorHtyr5BcnJheUxpc3TWp7PWy+a7+rfDzsqhozwvcD4KPHA+ICAgICAgICAgICAgNaGiQXJyYXlMaXN0yrXP1sHLQ2xvbmVhYmxlvdO/2qGitMu907/a1rvT0Mn5w/ehosO709C3vbeozOWhorHtyr5BcnJheUxpc3TWp7PWv8vCoaGjPC9wPgo8cD4gICAgICAgICAgICA2oaJBcnJheUxpc3TKtc/WwctTZXJpYWxpemFibGW907/aoaK0y73Tv9rWu9PQyfnD96Giw7vT0Le9t6jM5aGise3KvkFycmF5TGlzdNans9bQ8sHQu6+hory0v8nS1L2rQXJyYXlMaXN00tTB97XE0M7Kvc2ouf1PYmplY3RJbnB1dFN0cmVhbS9PYmplY3RPdXRwdXRTdHJlYW3AtNC0L7bBoaM8L3A+CjxwPjxicj4KPC9wPgo8aDI+yP2jukFycmF5TGlzdCBBUEk8L2gyPgo8cD4gPC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">// Collection中定义的API boolean add(E object) boolean addAll(Collection collection) void clear() boolean contains(Object object) boolean containsAll(Collection collection) boolean equals(Object object) int hashCode() boolean isEmpty() Iterator iterator() boolean remove(Object object) boolean removeAll(Collection collection) boolean retainAll(Collection collection) int size() T[] toArray(T[] array) Object[] toArray() // AbstractList中定义的API void add(int location, E object) boolean addAll(int location, Collection collection) E get(int location) int indexOf(Object object) int lastIndexOf(Object object) ListIterator listIterator(int location) ListIterator listIterator() E remove(int location) E set(int location, E object) List subList(int start, int end) // ArrayList新增的API Object clone() void ensureCapacity(int minimumCapacity) void trimToSize() void removeRange(int fromIndex, int toIndex)

总结:相对与AbstractCollection而言、多实现了List中新增的通过索引操作元素的方法。


四:ArrayList源码分析


package com.chy.collection.core;

import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.RandomAccess;
public class ArrayList
  
    extends AbstractList
   
     implements List
    
     , RandomAccess, Cloneable, java.io.Serializable { private static final long serialVersionUID = 8683452581122892189L; /** 保存ArrayList中元素的数组*/ private transient Object[] elementData; /** 保存ArrayList中元素的数组的容量、即数组的size*/ private int size; /** 使用指定的大小创建ArrayList*/ public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; } /** 使用默认的大小创建ArrayList*/ public ArrayList() { this(10); } /** * 使用指定的Collection构造ArrayList、构造之后的ArrayList中包含Collection中的元素、 * 这些元素的排序方式是按照ArrayList的Iterator返回他们时候的顺序排序的 */ public ArrayList(Collection
      c) { elementData = c.toArray(); size = elementData.length; // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } /** * 将此 ArrayList 实例的容量调整为列表的当前大小 */ public void trimToSize() { //此集合总共被修改的次数 modCount++; int oldCapacity = elementData.length; if (size < oldCapacity) { elementData = Arrays.copyOf(elementData, size); } } /** * 确保此ArrayList的最小容量能容纳下参数minCapacity指定的容量、 * 1、minCapacity大于原来容量、则将原来的容量增加(oldCapacity * 3)/2 + 1; * 2、若minCapacity仍然大于增加后的容量、则使用minCapacity作为ArrayList容量 * 3、若minCapacity不大于增加后的容量、则使用增加后的容量。 */ public void ensureCapacity(int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } } /** 返回此列表中的元素的个数*/ public int size() { return size; } /** 如果此列表中没有元素,则返回 true*/ public boolean isEmpty() { return size == 0; } /** 如果此列表中包含指定的元素,则返回 true。*/ public boolean contains(Object o) { return indexOf(o) >= 0; } /** 返回指定对象在ArrayList中存放的第一个位置索引、注意空值的处理和Object.equals(  extends Object o)的返回值、不存在的话返回-1*/ 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.equals(  extends Object o)的返回值、不存在的话返回-1*/ 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; } /** 返回一个当前集合的浅clone对象*/ 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 Cloneable throw new InternalError(); } } /** 将当前ArrayList转换成Object数组、注意操作使用此方法转换后的数组有可能抛异常*/ public Object[] toArray() { return Arrays.copyOf(elementData, size); } /** * 将当前ArrayList转换成与传入的T类型相同的数组、当传入的a的length小于ArrayList的size的时候、方法内部会生成一个新的T[]返回 * 如果传入的T[]的length大于ArrayList的size、则T[]从下标size开始到最后的元素都自动用null填充。 */ public 
       
         T[] toArray(T[] a) { if (a.length < size) // Make a new array of a's runtime type, but my contents: return (T[]) Arrays.copyOf(elementData, size, a.getClass()); System.arraycopy(elementData, 0, a, 0, size); if (a.length > size) a[size] = null; return a; } // Positional Access Operations /** 获取ArrayList中索引为index位置的元素*/ public E get(int index) { RangeCheck(index); return (E) elementData[index]; } /** 将ArrayList的索引为index处的元素使用指定的E元素替换、返回被替换的原来的元素值*/ public E set(int index, E element) { RangeCheck(index); E oldValue = (E) elementData[index]; elementData[index] = element; return oldValue; } /** 将指定元素E添加到ArrayList的结尾处*/ public boolean add(E e) { //确保ArrayList的容量能够添加新的的元素 ensureCapacity(size + 1); // Increments modCount!! elementData[size++] = e; return true; } /** 将指定元素添加到指定的索引处 、 * 注意: * 1、如果指定的index大于Object[] 的size或者小于0、则抛IndexOutOfBoundException * 2、检测Object[]是否需要扩容 * 3、 将从index开始到最后的元素后移一个位置、 * 4、将新添加的元素添加到index去。 */ public void add(int index, E element) { if (index > size || index < 0) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); ensureCapacity(size+1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } /** 与add类似、 * 1、将指定index处的元素删除、 * 2、将index之后的所有元素前一一个位置、最后一个 * 3、将最后一个元素设置为null、--size * * 返回被删除的元素。 */ public E remove(int index) { RangeCheck(index); modCount++; E oldValue = (E) elementData[index]; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // Let gc do its work return oldValue; } /** 删除Object[]中指定的元素Object 类似与contains方法与remove的结合体、只不过这里使用的是fastRemove方法去移除指定元素、移除成功则返回true*/ 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; // Let gc do its work } /** 清空ArrayList*/ public void clear() { modCount++; // Let gc do its work for (int i = 0; i < size; i++) elementData[i] = null; size = 0; } /** 将指定集合中的所有元素追加到ArrayList中(从最后开始追加)*/ public boolean addAll(Collection
         c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacity(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; } /** 将指定集合中的所有元素插入到idnex开始的后面位置处、原有的元素往后排*/ public boolean addAll(int index, Collection
         c) { if (index > size || index < 0) throw new IndexOutOfBoundsException( "Index: " + index + ", Size: " + size); Object[] a = c.toArray(); int numNew = a.length; ensureCapacity(size + numNew); // Increments modCount int numMoved = size - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew, numMoved); System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; } /** 移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。 * 1、将Object[] 从toIdnex开始之后的元素(包括toIndex处的元素)移到Object[]下标从fromIndex开始之后的位置 * 2、若有Object[]尾部要有剩余的位置则用null填充 */ protected void removeRange(int fromIndex, int toIndex) { modCount++; int numMoved = size - toIndex; System.arraycopy(elementData, toIndex, elementData, fromIndex, numMoved); // Let gc do its work int newSize = size - (toIndex-fromIndex); while (size != newSize) elementData[--size] = null; } /** 检测下标是否越界*/ private void RangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); } /** 将此ArrayList写入到ObjectOutputStream流中、先写ArrayList存放元素的Object[]长度、再将Object[]中的每个元素写入到ObjectOutputStream流中*/ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ // Write out element count, and any hidden stuff int expectedModCount = modCount; s.defaultWriteObject(); // Write out array length s.writeInt(elementData.length); // Write out all elements in the proper order. for (int i=0; i