1. 程式人生 > 其它 >2.集合-Collection介面

2.集合-Collection介面

集合介紹

Collection介面介紹

Map介面介紹

List介面

ArrayList原始碼分析

ArrayList初始化

		/**
     * 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.
     */
		//預設容量的空陣列
    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.
     */
		//list中的資料
    transient Object[] elementData; // non-private to simplify nested class access

    /**
     * The size of the ArrayList (the number of elements it contains).
     *
     * @serial
     */
		//list的大小
    private int size;

無參構造

/**
 * Constructs an empty list with an initial capacity of ten.
 */
public ArrayList() {
  	//將空陣列賦值到儲存資料的陣列中
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

有參構造

/**
 * 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
 */
public ArrayList(int initialCapacity) {
  	//如果傳的引數大於0
    if (initialCapacity > 0) {
        //那麼建立一個與該引數大小相等的陣列賦值到儲存資料的陣列中
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) { //如果傳的引數等於0
      	//將空陣列賦值到儲存資料的陣列中
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
      	//否則的話丟擲異常
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

第1次add()

/**
 * Appends the specified element to the end of this list.
 *
 * @param e element to be appended to this list
 * @return <tt>true</tt> (as specified by {@link Collection#add})
 */
public boolean add(E e) {
  	//size預設為0
    //ensureCapacityInternal(0 + 1)
    ensureCapacityInternal(size + 1);  // Increments modCount!!
  	//list[0] = e
  	//size++ = 1
    elementData[size++] = e;
    return true;
}
//此時minCapacity引數為:1
private void ensureCapacityInternal(int minCapacity) { 
  	//elementData在無參構造的時候賦值為:DEFAULTCAPACITY_EMPTY_ELEMENTDATA
  	//calculateCapacity(DEFAULTCAPACITY_EMPTY_ELEMENTDATA, 1)
  	//ensureExplicitCapacity(10)
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//此時elementData引數為:DEFAULTCAPACITY_EMPTY_ELEMENTDATA;minCapacity引數為:1
private static int calculateCapacity(Object[] elementData, int minCapacity) { 
  	//第一次add的時候入了此判斷
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
      	//Math.max(10, 1)
      	//return 10;
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}
//此時minCapacity引數為:10
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
  	//10 - 0 = 10 > 0進入判斷
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}
/**
 * Increases the capacity to ensure that it can hold at least the
 * number of elements specified by the minimum capacity argument.
 *
 * @param minCapacity the desired minimum capacity
 */
//此時minCapacity引數為:10
private void grow(int minCapacity) {
    // overflow-conscious code
  	//oldCapacity = 0
    int oldCapacity = elementData.length;
  	//這裡有個>>概念 叫按位右移運算子
  	//oldCapacity >> 1 = 0 >> 1 = 0
  	//newCapacity = 0 = 0 + 0
  	//計算新的容量 新容量為 老容量的1.5倍 第一次為0
    int newCapacity = oldCapacity + (oldCapacity >> 1);
  	// 0 - 10 = -10 < 0 進入此判斷
    if (newCapacity - minCapacity < 0)
      	//newCapacity = 10
        newCapacity = minCapacity;
  	//10 - (20億 - 8) < 0 所以不會進入此判斷
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
  	//儲存list資料的陣列為:elementData = new Object[]{null,null,null,null,null,null,null,null,null,null};
    elementData = Arrays.copyOf(elementData, newCapacity);
}

第2次add()

/**
 * Appends the specified element to the end of this list.
 *
 * @param e element to be appended to this list
 * @return <tt>true</tt> (as specified by {@link Collection#add})
 */
public boolean add(E e) {
  	//size = 1
  	//1 + 1 = 2;
    ensureCapacityInternal(size + 1);  // Increments modCount!!
  	//elementData[1] = e
  	//size++ = 2
    elementData[size++] = e;
    return true;
}
//minCapacity = 2
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//elementData = {e,null,null,null,null,null,null,null,null,null}
//minCapacity = 2
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
  	//不會進入上面的判斷了在這裡返回2
    return minCapacity;
}
//minCapacity = 2
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
  	//2 - 10 < 0不會進入此判斷了
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

第11次add()

public boolean add(E e) {
  	//size = 10
  	//10 + 1 = 11
    ensureCapacityInternal(size + 1);  // Increments modCount!!
  	//elementData[10] = e;
  	//size = 11;
    elementData[size++] = e;
    return true;
}
//minCapacity = 11
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//elementData = {e,e,e,e,e,e,e,e,e,e}
//minCapacity = 11
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
  	//再此返回11
    return minCapacity;
}
//minCapacity = 11
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
  	//11 - 10 = 1 > 0進入此判斷
    if (minCapacity - elementData.length > 0)
      	//minCapacity = 11
        grow(minCapacity);
}
/**
 * Increases the capacity to ensure that it can hold at least the
 * number of elements specified by the minimum capacity argument.
 *
 * @param minCapacity the desired minimum capacity
 */
//minCapacity = 11
private void grow(int minCapacity) {
    // overflow-conscious code
  	//oldCapacity = 10
    int oldCapacity = elementData.length;
  	//oldCapacity >> 1
  	//1010 -> 0101 = 5
  	//10 + 5 = 15
  	//newCapacity = 15
    int newCapacity = oldCapacity + (oldCapacity >> 1);
  	//15 - 11 = 4 > 0不會進入此判斷
    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 = {e,e,e,e,e,e,e,e,e,e,null,null,null,null,null}
    elementData = Arrays.copyOf(elementData, newCapacity);
}

get()

/**
 * Returns the element at the specified position in this list.
 *
 * @param  index index of the element to return
 * @return the element at the specified position in this list
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public E get(int index) {
  	//校驗下標
    rangeCheck(index);

    return elementData(index);
}
/**
 * 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) {
  	//如果下標大於等於size(陣列長度,那麼拋異常)
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

set()

/**
 * Replaces the element at the specified position in this list with
 * the specified element.
 *
 * @param index index of the element to replace
 * @param element element to be stored at the specified position
 * @return the element previously at the specified position
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public E set(int index, E element) {
  	//校驗下標索引
    rangeCheck(index);
		//獲得該下標下老的資料
    E oldValue = elementData(index);
  	//給該下標賦新的值
    elementData[index] = element;
  	//返回老的資料
    return oldValue;
}

remove()

/**
 * Removes the element at the specified position in this list.
 * Shifts any subsequent elements to the left (subtracts one from their
 * indices).
 *
 * @param index the index of the element to be removed
 * @return the element that was removed from the list
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public E remove(int index) {
  	//校驗下標索引
    rangeCheck(index);

    modCount++;
  	//獲取該下標下老的資料
    E oldValue = elementData(index);
		//elementData = {1,2,3,4,5,6,7,8,9,10};
  	//比如要刪除下標5的值 6
  	//10 - 5 - 1 = 4
  	//numMoved = 4
    int numMoved = size - index - 1;
  	//4 > 0進入此判斷
    if (numMoved > 0)
      	//源陣列 開始下標 目標陣列 開始下標 長度
      	//{1,2,3,4,5,6,7,8,9,10}
      	//{1,2,3,4,5,7,8,9,10}
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
  	//{1,2,3,4,5,7,8,9,10,null}
    elementData[--size] = null; // clear to let GC do its work
		//返回沒刪除之前的資料
    return oldValue;
}

LinkedList原始碼分析

Vector原始碼分析

Set介面

HashSet

TreeSet