java collection 集合源碼分析(一)

collection 爲java集合的接口,collection的接口繼承Iterablejava

public interface Collection<E> extends Iterable<E>

沒有本身在畫類圖了 找到網上有大哥畫的關係圖以下node

上圖中有個位置可能錯了,AbstrctList應該繼承自數組

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>

1、List(接口)安全

    一、ArrayListapp

        內部持有一個Object[] 數組     優化

 /**
     * Default initial capacity.
     */
    private static final int DEFAULT_CAPACITY = 10;  //默認大小

    /**
     * Shared empty array instance used for empty instances.
     */
    private static final Object[] 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 == EMPTY_ELEMENTDATA will be expanded to
     * DEFAULT_CAPACITY when the first element is added.
     */
    private transient Object[] elementData;

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

        全部的操做基於這個數組進行組織,通常不輕易對這個數組進行遍歷,通常多用system.arraycopy的方式進行操做,刪除的動做有時候依賴與gc來回收,以下刪除方法:
this

   /**
     * 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);

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

    二、LinkedList
spa

        LinkedList,內部持有一系列的Node ,node結構以下線程

private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

    從上能夠看出 node中 保存了前一個和後一個的節點信息,和數據,分爲三部分
code

    對節點的管理以下:

    transient int size = 0; //有多少節點
   
       /**
     * Pointer to first node.
      * Invariant: (first == null && last == null) ||
      *            (first.prev == null && first.item != null)
      */
     transient Node<E> first; //頭節點
 
     /**
      * Pointer to last node.
      * Invariant: (first == null && last == null) ||
      *            (last.next == null && last.item != null)
      */
     transient Node<E> last; //尾節點

    全部的操做圍繞對節點的增刪來操做,看一個添加全部的操做

    /**  
     * 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 LinkedList(Collection<? extends E> c) { 
        this();
        addAll(c);
    }   //構造
    
        /**
     * Appends all of the elements in the specified collection to the end of
     * this list, in the order that they are returned by the specified
     * collection's iterator.  The behavior of this operation is undefined if
     * the specified collection is modified while the operation is in
     * progress.  (Note that this will occur if the specified collection is
     * this list, and it's nonempty.)
     *
     * @param c collection containing elements to be added to this list
     * @return {@code true} if this list changed as a result of the call
     * @throws NullPointerException if the specified collection is null
     */
    public boolean addAll(Collection<? extends E> c) {
        return addAll(size, c);
    }
    
       /**
     * Inserts all of the elements in the specified collection into this
     * list, starting at the specified position.  Shifts the element
     * currently at that position (if any) and any subsequent elements to
     * the right (increases their indices).  The new elements will appear
     * in the list in the order that they are returned by the
     * specified collection's iterator.
     *
     * @param index index at which to insert the first element
     *              from the specified collection
     * @param c collection containing elements to be added to this list
     * @return {@code true} if this list changed as a result of the call
     * @throws IndexOutOfBoundsException {@inheritDoc}
     * @throws NullPointerException if the specified collection is null
     */
    public boolean addAll(int index, Collection<? extends E> c) {
        checkPositionIndex(index);

        Object[] a = c.toArray();
        int numNew = a.length;
        if (numNew == 0)
            return false;

        Node<E> pred, succ;
        if (index == size) {
            succ = null;
            pred = last;
        } else {
            succ = node(index);  //返回索引處的特徵節點,這個方法會優化從頭部仍是從尾部查找的過程具體參看源碼
            pred = succ.prev;
        }

        for (Object o : a) {
            @SuppressWarnings("unchecked") E e = (E) o;
            Node<E> newNode = new Node<>(pred, e, null);
            if (pred == null)
                first = newNode;
            else
                pred.next = newNode;
            pred = newNode;
        }  //添加過程

        if (succ == null) {
            last = pred;
        } else {
            pred.next = succ;
            succ.prev = pred;
        }

        size += numNew;
        modCount++;
        return true;
    }

    三、Vector

        arrayList相似,源碼多處增長了synchronized 關鍵字,線程安全

2、Set(接口)

    一、HashSet

        HashSet內部實際持有的是一個hashmap對象,全部的操做都是經過操做map實現,這個map是無值,只有key,

        內部的一個hashmap對象

    private transient HashMap<E,Object> map;

    public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); //開闢一個比原有集合4/3大小的集合。默認16
        addAll(c);
    }

        看一個獲取迭代器的方法

    /**
     * Returns an iterator over the elements in this set.  The elements
     * are returned in no particular order.
     *
     * @return an Iterator over the elements in this set
     * @see ConcurrentModificationException
     */
    public Iterator<E> iterator() {
        return map.keySet().iterator();
    }

    二、TreeSet

        TreeSet也是經過map來實現

private transient NavigableMap<E,Object> m; //這裏使用的是NavigableMap,這個繼承自SortedMap接口 since1.6以後

        其餘的方法都是調用map的實現,在map中在看

Map 單立一章來寫把


ps:以上的源碼來自openjdk7u75-b13版本

相關文章
相關標籤/搜索