ArrayList
1、开始 public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable 继承了抽象类AbstractList,实现了List接口,RandomAccess接口(数据随机存储),Cloneable接口(可克隆),Serializable接口(可序列化) 2、属性 //用于存放元素的数组,不可进行序列化 private transient Object[] elementData; //已经存放的元素的个数 private int size; 3、构造器 //指定列表大小 public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity); this.elementData = new Object[initialCapacity]; } //默认列表大小为10 public ArrayList() { this(10); } //有初始内容的列表 public ArrayList(Collection<? extends E> 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); } 4、方法 1)、添加 //向列表中添加元素,返回是否添加成功 public boolean add(E e) { //是否扩容 ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } //向列表中指定的位置添加元素,其他的元素后移 public void add(int index, E element) { //检测下标是否合法,下标范围[0,size] rangeCheckForAdd(index); //是否扩容 ensureCapacityInternal(size + 1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } 2)、获取和设置 //根据下标返回元素 E elementData(int index) { return (E) elementData[index]; } //根据下标获取元素 public E get(int index) { //检测下标是否合法,下标范围[0,size) rangeCheck(index); return elementData(index); } //设置列表中指定位置中的元素,并返回该位置的旧数据 public E set(int index, E element) { //检测下标是否合法,下标范围[0,size) rangeCheck(index); E oldValue = elementData(index); elementData[index] = element; return oldValue; } 3)、删除 //删除指定位置的元素,并返回要删除的元素 public E remove(int index) { //检测下标是否合法,下标范围[0,size) 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; // Let gc do its work return oldValue; } //删除指定的元素,返回是否删除成功,分为删除的元素是否为null,之后分别进行遍历删除 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 remove method that skips bounds checking and does not * return the value removed. */ private void fastRemove(int index) { //记录更改的次数 modCount++; //需要移动的元素个数 int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); //利于GC elementData[--size] = null; // Let gc do its work } 4)、扩容检测 //目标容量与当前容量进行比较,是否进行扩容 private void ensureCapacityInternal(int minCapacity) { //扩容相当于一次更改 modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } /** * The maximum size of array to allocate. * Some VMs reserve some header words in an array. * Attempts to allocate larger arrays may result in * OutOfMemoryError: Requested array size exceeds VM limit */ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //扩容,在原来的基础上增加0.5,即容量是原来的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); } //获取最大的列表容量 private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } 5)、范围检测 //下标范围[0,size) /** * Checks if the given index is in range. If not, throws an appropriate * runtime exception. This method does *not* check if the index is * negative: It is always used immediately prior to an array access, * which throws an ArrayIndexOutOfBoundsException if index is negative. */ private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } //下标范围[0,size],用于add(index)与addAll方法 /** * A version of rangeCheck used by add and addAll. */ private void rangeCheckForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } /** * Constructs an IndexOutOfBoundsException detail message. * Of the many possible refactorings of the error handling code, * this "outlining" performs best with both server and client VMs. */ private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size; } 6)、获取集合间的交集和差集 //集合差集 public boolean removeAll(Collection<?> c) { return batchRemove(c, false); } //集合交集 public boolean retainAll(Collection<?> 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) elementData[w++] = elementData[r]; } finally { // Preserve behavioral compatibility with AbstractCollection, // even if c.contains() throws. if (r != size) { System.arraycopy(elementData, r, elementData, w, size - r); w += size - r; } if (w != size) { for (int i = w; i < size; i++) elementData[i] = null; modCount += size - w; size = w; modified = true; } } return modified; } 7)、将集合添加到列表中 //将集合添加到列表末尾 public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; } //将集合添加到列表中指定的位置 public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(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; } 8)、基础方法 //获取列表元素个数 public int size() { return size; } //列表是否为空,即大小是否为0 public boolean isEmpty() { return size == 0; } //列表是否包含该元素 public boolean contains(Object o) { return indexOf(o) >= 0; } //查找元素在列表中第一次出现的位置,循环遍历 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; } //查找元素在列表中的最后一次出现的位置,倒序遍历 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; } //将列表转换为数组 public Object[] toArray() { return Arrays.copyOf(elementData, size); } //将列表转换给指定的数组 @SuppressWarnings("unchecked") public <T> 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; } //缩减列表中不存在的元素 public void trimToSize() { modCount++; int oldCapacity = elementData.length; if (size < oldCapacity) { elementData = Arrays.copyOf(elementData, size); } } 9)、迭代器,都支持fail-fast机制,可能会抛出ConcurrentModificationException异常 //列表迭代器 public ListIterator<E> listIterator(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: "+index); return new ListItr(index); } //列表迭代器 public ListIterator<E> listIterator() { return new ListItr(0); } //迭代器 public Iterator<E> iterator() { return new Itr(); } //迭代器定义 private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; //是否还有元素 public boolean hasNext() { return cursor != size; } //获取下一个元素 @SuppressWarnings("unchecked") public E next() { checkForComodification(); //当前元素下标 int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); //下一个元素的下标 cursor = i + 1; //指定当前最后一个下标 return (E) elementData[lastRet = i]; } //删除当前最后一个元素,并指定当前位置的下标 public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { //删除元素 ArrayList.this.remove(lastRet); //指定当前下标 cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
//列表迭代器定义 private class ListItr extends Itr implements ListIterator<E> { ListItr(int index) { super(); cursor = index; } //是否有前一个 public boolean hasPrevious() { return cursor != 0; } //获取下一个索引 public int nextIndex() { return cursor; } //获取前一个索引 public int previousIndex() { return cursor - 1; } //获取前一个元素 @SuppressWarnings("unchecked") public E previous() { checkForComodification(); int i = cursor - 1; if (i < 0) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i; return (E) elementData[lastRet = i]; } //设置元素 public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.set(lastRet, e); } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } //添加元素 public void add(E e) { checkForComodification(); try { int i = cursor; ArrayList.this.add(i, e); cursor = i + 1; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } }
10)、子列表,更改子列表时,会影响到父列表,但更改父列表时,子列表将抛出异常ConcurrentModificationException //获取子列表 public List<E> subList(int fromIndex, int toIndex) { subListRangeCheck(fromIndex, toIndex, size); return new SubList(this, 0, fromIndex, toIndex); } //子列表检测 static void subListRangeCheck(int fromIndex, int toIndex, int size) { if (fromIndex < 0) throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); if (toIndex > size) throw new IndexOutOfBoundsException("toIndex = " + toIndex); if (fromIndex > toIndex) throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); } //以下是子列表对象中的方法 //子列表构造器 SubList(AbstractList<E> parent, int offset, int fromIndex, int toIndex) { this.parent = parent;//父列表对象 this.parentOffset = fromIndex; this.offset = offset + fromIndex; this.size = toIndex - fromIndex;//子列表大小 this.modCount = ArrayList.this.modCount; //子列表更改记录,必须跟父列表保持同步,否则抛出异常ConcurrentModificationException } //往指定位置添加元素 public void add(int index, E e) { rangeCheckForAdd(index); checkForComodification(); //往父列表中添加元素后,需要将更改记录同步到子列表中 parent.add(parentOffset + index, e); this.modCount = parent.modCount; this.size++; } //删除指定位置的元素 public E remove(int index) { rangeCheck(index); checkForComodification(); E result = parent.remove(parentOffset + index); //往父列表中删除元素后,需要将更改记录同步到子列表中 this.modCount = parent.modCount; this.size--; return result; } //检测子列表与父列表的更改状态是否一致 private void checkForComodification() { if (ArrayList.this.modCount != this.modCount) throw new ConcurrentModificationException(); }
ArrayList的遍历方式 1)、根据索引值进行遍历 2)、通过迭代器进行遍历 3)、通过foreach ArrayList和LinkedList 1)、ArrayList是基于动态数组实现的数据结构,而LinkedList是基于链表实现的数据结构 2)、对于随机访问get和set,ArrayList优于LinkedList,这是由于LinkedList需要移动指针 3)、对于新增和删除操作add和remove,LinkedList比较占优势,这是由于ArrayList需要移动数据 ArrayList和Vector 1)、Vector和ArrayList实现几乎一样,唯一不同的是Vector是同步类(synchronized),故开销比ArrayList大,访问慢 2)、Vector每次扩容后其大小是原来的2倍,而ArrayList是1.5倍 3)、Vector还有一个子类Stack
参考资料:
http://www.importnew.com/17440.html
http://anxpp.com/index.php/archives/664/