Java ArrayList源代码学习笔记

<span style="font-size:18px;"> private static final int MIN_CAPACITY_INCREMENT = 12;</span>

Object[] newArray = new Object[s +(s < (MIN_CAPACITY_INCREMENT / 2) ?MIN_CAPACITY_INCREMENT : s >> 1)];

如上,是增量的计算方法。

构造方法:

<span style="font-size:18px;">public ArrayList(int capacity) {if (capacity < 0) {throw new IllegalArgumentException("capacity < 0: " + capacity);}array = (capacity == 0 ? EmptyArray.OBJECT : new Object[capacity]);}</span>根据capacity确定大小,若小于0则抛出异常。否则,如果为0,则初始化空数据;大于0,则根据capacity的大小初始化数组。

注意:如果只有两种情况,,就不要用if ,else,可以用(..? ..:…)

public ArrayList(Collection<? extends E> collection) {if (collection == null) {throw new NullPointerException("collection == null");}Object[] a = collection.toArray();if (a.getClass() != Object[].class) {Object[] newArray = new Object[a.length];System.arraycopy(a, 0, newArray, 0, a.length);a = newArray;}array = a;size = a.length;}数组的快速复制,可以使用:System.arraycopy(a, 0, newArray, 0, a.length);

贴下ArrayList的源码:

@Override public boolean add(E object) {Object[] a = array;int s = size;if (s == a.length) {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) {throwIndexOutOfBoundsException(index, s);}if (s < a.length) {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) {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) {Object[] newPart = collection.toArray();int newPartSize = newPart.length;if (newPartSize == 0) {return false;}Object[] a = array;int s = size;int newSize = s + newPartSize; // If add overflows, arraycopy will failif (newSize > a.length) {int newCapacity = newCapacity(newSize – 1); // ~33% growth roomObject[] 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()}*/@Overridepublic boolean addAll(int index, Collection<? extends E> collection) {int s = size;if (index > s || index < 0) {throwIndexOutOfBoundsException(index, s);}Object[] newPart = collection.toArray();int newPartSize = newPart.length;if (newPartSize == 0) {return false;}Object[] a = array;int newSize = s + newPartSize; // If add overflows, arraycopy will failif (newSize <= a.length) {System.arraycopy(a, index, a, index + newPartSize, s – index);} else {int newCapacity = newCapacity(newSize – 1); // ~33% growth roomObject[] 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);}/*** Removes all elements from this {@code ArrayList}, leaving it empty.** @see #isEmpty* @see #size*/@Override public void clear() {if (size != 0) {Arrays.fill(array, 0, size, null);size = 0;modCount++;}}/*** Returns a new {@code ArrayList} with the same elements, the same size and* the same capacity as this {@code ArrayList}.** @return a shallow copy of this {@code ArrayList}* @see java.lang.Cloneable*/@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;}@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 leaksize = 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 leaksize = 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 leaksize = 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) {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;}/*** Returns an array containing all elements contained in this* {@code ArrayList}. If the specified array is large enough to hold the* elements, the specified array is used, otherwise an array of the same* type is created. If the specified array is used and is larger than this* {@code ArrayList}, the array element following the collection elements* is set to null.** @param contents*the array.* @return an array of the elements from this {@code ArrayList}.* @throws ArrayStoreException*when the type of an element in this {@code ArrayList} cannot*be stored in the type of the specified array.*/@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() {int s = size;if (s == array.length) {return;}if (s == 0) {array = EmptyArray.OBJECT;} else {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 leakremovalIndex = -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 iteratorIterator<?> 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();}} }

一个积极奋进的目标,一种矢志不渝的追求。

Java ArrayList源代码学习笔记

相关文章:

你感兴趣的文章:

标签云: