1.1 一个List接口可调节数组的实现。实现所有List操作,并且支持所有元素,包括null。除了实现List接口,实现类提供方法调节内部数组的大小,这个实现类大约等于Vector,除了不是锁的。
1.2 等等方法运行都是时间都是常数,增加一个元素O(n),其他大约是一个线性时间。常数因子小于LinkedList
1.3 每一个ArrayList实例有一个容量。容量和内部数组的大小相等。容量总是大于等于list的size。当元素加入的时候,list的容量自动增长,增长的政策不是指定的。
1.4 程序可以事先在添加较多元素之前使用ensureCapacity()增长实例的容量,这可以减少扩容的次数。
1.5 注意ArrayList不是同步的1,如果多个线程同时操作arraylist实例,并且至少一个线程在结构上操作了list,必须外部锁上。
1.6 最好使用Coll....这个方法避免意外。
1.7 listArray的等等方法返回的iterators是快速失败的,在iterator创建之后,任何非自己的结构上的操作都会抛出ConcurrentModificationException异常,然后iterator快速失败,而不是冒着任意的任意的不确定的操作在将来一个不确定的时间
1.8 注意迭代器的快速失败机制不可能做任何保证,通常来说不可能做任何保证在存在步同步的并发更改的时候。快速失败机制尽最大努力抛出....异常。快速失败机制只用来预防bug。
2.属性
/** * Default initial capacity.
默认的容量 */ private static final int DEFAULT_CAPACITY = 10; /** * Shared empty array instance used for empty instances.
*/ private static final Object[] EMPTY_ELEMENTDATA = {}; /** * Shared empty array instance used for default sized empty instances. We * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when * first element is added.
默认大小的空实例,我们和EMPTY_ELEMENTDATA区分,确定第一个元素插入的时候,内部数组该怎么膨胀
事实上如果是默认的,则会一下子增长到10 */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. Any * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA * will be expanded to DEFAULT_CAPACITY when the first element is added.
集合内部存储元素的数组,集合的容量就是内部数组的长度,事实上如果elementData==...
则会在第一个元素添加的时候扩展到10.内部存储元素的数组
*/ transient Object[] elementData; // non-private to simplify nested class access /** * The size of the ArrayList (the number of elements it contains).
集合的大小,即存储了几个元素 * * @serial */ private int size;
3.构造器
/** * Constructs an empty list with the specified initial capacity. * * @param initialCapacity the initial capacity of the list * @throws IllegalArgumentException if the specified initial capacity * is negative
这样看源代码就是只要指定了大小就不会使用默认的10. */ public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }
/** * Constructs an empty list with an initial capacity of ten. 这个就是初始容量10*/ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
/** * Constructs a list containing the elements of the specified * collection, in the order they are returned by the collection‘s * iterator. * * @param c the collection whose elements are to be placed into this list * @throws NullPointerException if the specified collection is null */ public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class)
// 这里是把elementdata又转换成object数组,不知道具体什么原因。 elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } }
4.方法
/** * Trims the capacity of this <tt>ArrayList</tt> instance to be the * list‘s current size. An application can use this operation to minimize * the storage of an <tt>ArrayList</tt> instance.
只要trimToSize之后elemdata就不会再只向默认的数组了吗 */ public void trimToSize() { modCount++; if (size < elementData.length) { elementData = (size == 0) ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size); } }
/** * Increases the capacity of this <tt>ArrayList</tt> instance, if * necessary, to ensure that it can hold at least the number of elements * specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity */ public void ensureCapacity(int minCapacity) { int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) // any size if not default element table ? 0 // larger than default for default empty table. It‘s already // supposed to be at default size. : DEFAULT_CAPACITY; if (minCapacity > minExpand) { ensureExplicitCapacity(minCapacity); } }
// 一个私有的方法如果是默认的数组则返回指定的大小就要用默认的容量 //即要保证容量大于等于默认的10 //不是默认的数组即直接返回指定的大就可以了 private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; }
//这个第二部调用②计算要扩容的大小
private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; } //这个第一步调用① private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } //这里第三步调用③如果最小容量大于数组的长度就说明要扩容了 private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); }
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();
//这里如果比最大的int值减8还大就选择int的最大值 return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
/** * Returns the number of elements in this list. * * @return the number of elements in this list */ public int size() { return size; }
/** * Returns <tt>true</tt> if this list contains no elements. * * @return <tt>true</tt> if this list contains no elements */ public boolean isEmpty() { return size == 0; }
/** * Returns the index of the first occurrence of the specified element * in this list, or -1 if this list does not contain the element. * More formally, returns the lowest index <tt>i</tt> such that * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, * or -1 if there is no such index. */ 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; }
/** * Returns <tt>true</tt> if this list contains the specified element. * More formally, returns <tt>true</tt> if and only if this list contains * at least one element <tt>e</tt> such that * <tt>(o==null ? e==null : o.equals(e))</tt>. * * @param o element whose presence in this list is to be tested * @return <tt>true</tt> if this list contains the specified element */ public boolean contains(Object o) { return indexOf(o) >= 0; }
/** * Returns the index of the last occurrence of the specified element * in this list, or -1 if this list does not contain the element. * More formally, returns the highest index <tt>i</tt> such that * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, * or -1 if there is no such index. */ 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; }
/** * Returns a shallow copy of this <tt>ArrayList</tt> instance. (The * elements themselves are not copied.) * * @return a clone of this <tt>ArrayList</tt> instance */ 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(e); } }
/** * Returns an array containing all of the elements in this list * in proper sequence (from first to last element). * * <p>The returned array will be "safe" in that no references to it are * maintained by this list. (In other words, this method must allocate * a new array). The caller is thus free to modify the returned array. * * <p>This method acts as bridge between array-based and collection-based * APIs. * * @return an array containing all of the elements in this list in * proper sequence */ public Object[] toArray() { return Arrays.copyOf(elementData, size); }
原文:https://www.cnblogs.com/guxiaohu/p/11743301.html