java源碼分析之ArrayList

package java.util;
/**
 * 繼承自 AbstractList ,實現List<E>(集合), RandomAccess(標記接口,支持快速隨機訪問),
 * Cloneable(實現對象的淺拷貝), java.io.Serializable(序列化)接口 (非線程安全)
 */
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
	private static final long serialVersionUID = 8683452581122892189L;

	/**
	 * 定義默認容量爲 10
	 */
	private static final int DEFAULT_CAPACITY = 10;

	/**
	 * 定義一個空集合
	 */
	private static final Object[] EMPTY_ELEMENTDATA = {};

	/**
	 * 定義一個空的數組
	 */
	private transient Object[] elementData;

	/**
	 * 定義一個值 用於表示集合的元素數量 (元素數量不一定等於集合容量)
	 */
	private int size;

	/**
	 * 構造具有指定初始容量的空集合
	 */
	public ArrayList(int initialCapacity) {
		super();
		if (initialCapacity < 0)
			throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
		this.elementData = new Object[initialCapacity];
	}

	/**
	 * 構造初始容量爲 10 的空集合.
	 */
	public ArrayList() {
		super();
		this.elementData = EMPTY_ELEMENTDATA;
	}

	/**
	 * 按照集合迭代器返回的順序構造包含指定集合元素的集合
	 */
	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);
	}

	/**
	 * 去掉集合中的多餘位置,優化存儲(以實際元素個數爲集合容量大小)
	 */
	public void trimToSize() {
		modCount++;
		if (size < elementData.length) {
			elementData = Arrays.copyOf(elementData, size);
		}
	}

	/**
	 * 增加ArrayList實例的容量,如果有必要,確保它至少能容納的最小容量爲參數指定元素個數。
	 */
	public void ensureCapacity(int minCapacity) {
		int minExpand = (elementData != EMPTY_ELEMENTDATA) ? 0 : DEFAULT_CAPACITY;
		if (minCapacity > minExpand) {
			ensureExplicitCapacity(minCapacity);
		}
	}

	// 判斷集合默認容量與指定最小容量的大小(取大)
	private void ensureCapacityInternal(int minCapacity) {
		if (elementData == 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;

	/**
	 * 增加容量(每次1.5倍),確保集合的最小容量能容納指定元素數量。
	 */
	private void grow(int minCapacity) {
		int oldCapacity = elementData.length;
		// 注意此處擴充capacity的方式是將其向右一位再加上原來的數,實際上是擴充了1.5倍(原始容量x3)/2 + 1
		int newCapacity = oldCapacity + (oldCapacity >> 1);
		//如果還不夠,則直接將minCapacity設置爲當前容量 
		if (newCapacity - minCapacity < 0)
			newCapacity = minCapacity;
		//如果還不夠,則直接將Interger的容量作爲空間
		if (newCapacity - MAX_ARRAY_SIZE > 0)
			newCapacity = hugeCapacity(minCapacity);
		elementData = Arrays.copyOf(elementData, newCapacity);
	}

	/**
	 * 返回指定集合空間的最大值(Integer的最大值)
	 */
	private static int hugeCapacity(int minCapacity) {
		if (minCapacity < 0)
			throw new OutOfMemoryError();
		return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
	}

	/**
	 * 返回集合空間的實際大小
	 */
	public int size() {
		return size;
	}

	/**
	 * 判斷 集體是否爲空
	 */
	public boolean isEmpty() {
		return size == 0;
	}

	/**
	 * 判斷集合是否包含指定元素
	 */
	public boolean contains(Object o) {
		return indexOf(o) >= 0;
	}

	/**
	 * 返回指定元素在集合中首次出現的索引位置(正向匹配)如無,則返回 -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;
	}

	/**
	 * 返回指定元素最後出現的索引位置(反向匹配)如無,則返回 -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;
	}

	/**
	 * 返回該arraylis實例淺拷貝 (元素本身不被複制)Object的 clone()方法
	 */
	public Object clone() {
		try {
			@SuppressWarnings("unchecked")
			ArrayList<E> v = (ArrayList<E>) super.clone();
			v.elementData = Arrays.copyOf(elementData, size);
			v.modCount = 0;
			return v;
		} catch (CloneNotSupportedException e) {
			throw new InternalError();
		}
	}

	/**
	 * 返回包含此集合中所有元素按適當順序(從第一個到最後一個元素)組成的Object數組
	 */
	public Object[] toArray() {
		return Arrays.copyOf(elementData, size);
	}

	/**
	 * 返回包含此集合中所有元素(從第一個到最後一個元素)組成的數組;
	 * 如果傳入數組的長度小於集合size,返回一個新的數組,大小爲size,類型與傳入數組相同。所傳入數組長度與size相等,
	 * 則將elementData複製到傳入數組中並返回傳入的數組。若傳入數組長度大於size,除了複製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) {
		// 判斷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); // Increments modCount!!
		elementData[size++] = e;
		return true;
	}

	/**
	 * 向集合指定位置添加元素(同時增加集合容量)
	 */
	public void add(int index, E element) {
		rangeCheckForAdd(index);
		ensureCapacityInternal(size + 1);
		// 實現數組間的複製(源數組,源數組複製的起始位置,目標數據,目標數組放置的起始位置,複製的長度)
		// System.arraycopy只是把index位置及其後面的元素,拷貝到數組的index+1及其後面的位置中,
		// 也就是把index及其後面的元素全部後移一位。 最後,把新的元素放到數組的index位置
		System.arraycopy(elementData, index, elementData, index + 1, size - index);
		elementData[index] = element;
		size++;
	}

	/**
	 * 移除指定位置的元素(同時減少集合容量:將最後一位賦值爲Null,以便垃圾回收)
	 */
	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; // clear to let GC do its work
		return oldValue;
	}

	/**
	 * 刪除集合中某元素(如爲空,則刪除數組中值爲空的值)返回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; 
		//從 index+1 開始,後面的元素依次替換前面的元素
		if (numMoved > 0)
			System.arraycopy(elementData, index + 1, elementData, index, numMoved);
		//將最後一個元素設置爲Null,以便垃圾回收
		elementData[--size] = null; // clear to let GC do its work
	}

	/**
	 * 刪除集合中所有的元素(設置所有值爲null,以便垃圾回收)
	 */
	public void clear() {
		modCount++;
		// clear to let GC do its work
		for (int i = 0; i < size; i++)
			elementData[i] = null;
		size = 0;
	}

	/**
	 * 按照指定集合中的元素順序將所有元素添加到現有集合的末尾(如果操作過程中修改指定集合,操作爲空)
	 */
	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;
	}

	/**
	 * 刪除集合中fromIndex到toIndex之間的所有元素。將剩下的元素左移並減少它們的索引
	 */
	protected void removeRange(int fromIndex, int toIndex) {
		modCount++;
		int numMoved = size - toIndex;
		System.arraycopy(elementData, toIndex, elementData, fromIndex, numMoved);

		// clear to let GC do its work
		int newSize = size - (toIndex - fromIndex);
		for (int i = newSize; i < size; i++) {
			elementData[i] = null;
		}
		size = newSize;
	}

	/**
	 * 檢查指定index是否越界
	 */
	private void rangeCheck(int index) {
		if (index >= size)
			throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
	}

	/**
	 * 判斷指定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;
	}

	/**
	 * 刪除集合中等於指定集合中的元素的元素
	 */
	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) {
				// clear to let GC do its work
				for (int i = w; i < size; i++)
					elementData[i] = null;
				modCount += size - w;
				size = w;
				modified = true;
			}
		}
		return modified;
	}

	/**
	 * 將集合保存爲一個流,即序列化,將 容量和元素值信息寫入流中
	 */
	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
		// Write out element count, and any hidden stuff
		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;
		// Read in size, and any hidden stuff
		s.defaultReadObject();
		// Read in capacity
		s.readInt(); // ignored

		if (size > 0) {
			// 分配集合空間根據集合長度,而不是容量
			ensureCapacityInternal(size);

			Object[] a = elementData;
			// 按適當順序讀入所有元素
			for (int i = 0; i < size; i++) {
				a[i] = s.readObject();
			}
		}
	}

	/**
	 * 返回一個從index開始迭代的實例(建立在AbstractList的遍歷基礎上)
	 */
	public ListIterator<E> listIterator(int index) {
		if (index < 0 || index > size)
			throw new IndexOutOfBoundsException("Index: " + index);
		return new ListItr(index);
	}

	/**
	 * 返回一個從從0開始的迭代實例
	 */
	public ListIterator<E> listIterator() {
		return new ListItr(0);
	}

	/**
	 * 返回一個迭代器實例(包含hasNext,next,remove等操作)
	 */
	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();
		}
	}

	/**
	 * 內部迭代類,繼承Itr,實現ListIterator
	 */
	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();
			}
		}
	}

	/**
	 * 返回集合中從fromIndex到toIndex的元素構成一個新的集合
	 */
	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 + ")");
	}

	private class SubList extends AbstractList<E> implements RandomAccess {
		private final AbstractList<E> parent;
		private final int parentOffset;
		private final int offset;
		int size;

		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;
		}

		public E set(int index, E e) {
			rangeCheck(index);
			checkForComodification();
			E oldValue = ArrayList.this.elementData(offset + index);
			ArrayList.this.elementData[offset + index] = e;
			return oldValue;
		}

		public E get(int index) {
			rangeCheck(index);
			checkForComodification();
			return ArrayList.this.elementData(offset + index);
		}

		public int size() {
			checkForComodification();
			return this.size;
		}

		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;
		}

		protected void removeRange(int fromIndex, int toIndex) {
			checkForComodification();
			parent.removeRange(parentOffset + fromIndex, parentOffset + toIndex);
			this.modCount = parent.modCount;
			this.size -= toIndex - fromIndex;
		}

		public boolean addAll(Collection<? extends E> c) {
			return addAll(this.size, c);
		}

		public boolean addAll(int index, Collection<? extends E> c) {
			rangeCheckForAdd(index);
			int cSize = c.size();
			if (cSize == 0)
				return false;

			checkForComodification();
			parent.addAll(parentOffset + index, c);
			this.modCount = parent.modCount;
			this.size += cSize;
			return true;
		}

		public Iterator<E> iterator() {
			return listIterator();
		}

		public ListIterator<E> listIterator(final int index) {
			checkForComodification();
			rangeCheckForAdd(index);
			final int offset = this.offset;

			return new ListIterator<E>() {
				int cursor = index;
				int lastRet = -1;
				int expectedModCount = ArrayList.this.modCount;

				public boolean hasNext() {
					return cursor != SubList.this.size;
				}

				@SuppressWarnings("unchecked")
				public E next() {
					checkForComodification();
					int i = cursor;
					if (i >= SubList.this.size)
						throw new NoSuchElementException();
					Object[] elementData = ArrayList.this.elementData;
					if (offset + i >= elementData.length)
						throw new ConcurrentModificationException();
					cursor = i + 1;
					return (E) elementData[offset + (lastRet = i)];
				}

				public boolean hasPrevious() {
					return cursor != 0;
				}

				@SuppressWarnings("unchecked")
				public E previous() {
					checkForComodification();
					int i = cursor - 1;
					if (i < 0)
						throw new NoSuchElementException();
					Object[] elementData = ArrayList.this.elementData;
					if (offset + i >= elementData.length)
						throw new ConcurrentModificationException();
					cursor = i;
					return (E) elementData[offset + (lastRet = i)];
				}

				public int nextIndex() {
					return cursor;
				}

				public int previousIndex() {
					return cursor - 1;
				}

				public void remove() {
					if (lastRet < 0)
						throw new IllegalStateException();
					checkForComodification();

					try {
						SubList.this.remove(lastRet);
						cursor = lastRet;
						lastRet = -1;
						expectedModCount = ArrayList.this.modCount;
					} catch (IndexOutOfBoundsException ex) {
						throw new ConcurrentModificationException();
					}
				}

				public void set(E e) {
					if (lastRet < 0)
						throw new IllegalStateException();
					checkForComodification();

					try {
						ArrayList.this.set(offset + lastRet, e);
					} catch (IndexOutOfBoundsException ex) {
						throw new ConcurrentModificationException();
					}
				}

				public void add(E e) {
					checkForComodification();

					try {
						int i = cursor;
						SubList.this.add(i, e);
						cursor = i + 1;
						lastRet = -1;
						expectedModCount = ArrayList.this.modCount;
					} catch (IndexOutOfBoundsException ex) {
						throw new ConcurrentModificationException();
					}
				}

				final void checkForComodification() {
					if (expectedModCount != ArrayList.this.modCount)
						throw new ConcurrentModificationException();
				}
			};
		}

		public List<E> subList(int fromIndex, int toIndex) {
			subListRangeCheck(fromIndex, toIndex, size);
			return new SubList(this, offset, fromIndex, toIndex);
		}

		private void rangeCheck(int index) {
			if (index < 0 || index >= this.size)
				throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
		}

		private void rangeCheckForAdd(int index) {
			if (index < 0 || index > this.size)
				throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
		}

		private String outOfBoundsMsg(int index) {
			return "Index: " + index + ", Size: " + this.size;
		}

		private void checkForComodification() {
			if (ArrayList.this.modCount != this.modCount)
				throw new ConcurrentModificationException();
		}
	}
}

總結:

1.ArrayList  是基於動態數組的 可以自動增長空間容量的集合.

2.對於隨機訪問集合中的元素,使用arrayList 效率比較高.

3.arrayList 插入或者刪除元素都將對後面的剩餘元素進行移動,操作量比較大(末尾插入不需要).

4.通過索引進行遍歷速度最快(for循環list.size()),通過迭代器遍歷速度最慢(Itreator).

5.非線性安全,無法自動同步.如需線性安全,可使用vector.

6.直接刪除元素(remove(Object o))需要遍歷數組,如果刪除索引(remove(int index)),不需要遍歷數組.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章