1. 程式人生 > >JAVA原始碼閱讀之java.util—List

JAVA原始碼閱讀之java.util—List

List

List被宣告為一個介面,程式碼量很少,只聲明瞭方法。

public interface List<E> extends Collection<E> {
	int size();
	boolean isEmpty();
	boolean contains(Object o);
	Iterator<E> iterator();
	Object[] toArray();
	<T> T[] toArray(T[] a);
	boolean add(E e);
	boolean remove(Object o);
	boolean containsAll
(Collection<?> c); boolean addAll(Collection<? extends E> c); ... @SuppressWarnings({"unchecked", "rawtypes"}) default void sort(Comparator<? super E> c) { Object[] a = this.toArray(); Arrays.sort(a, (Comparator) c); ListIterator<E> i = this
.listIterator(); for (Object e : a) { i.next(); i.set((E) e); } } void clear(); boolean equals(Object o); int hashCode(); E get(int index); E set(int index, E element); void add(int index, E element); E remove(int index); int
indexOf(Object o); int lastIndexOf(Object o); ListIterator<E> listIterator(); ListIterator<E> listIterator(int index); List<E> subList(int fromIndex, int toIndex); @Override default Spliterator<E> spliterator() { return Spliterators.spliterator(this, Spliterator.ORDERED); } }

ArrayList

ArrayList繼承了AbstractList(AbstractList給出了List介面中的一些基本實現),聲明瞭一個儲存陣列transient Object[] elementData; 以後所有的操作基本都跟elementData陣列相關,不能儲存基本資料型別。size為陣列的大小,modCount為List被修改的次數。 第一個元素新增後,陣列的容量擴充到10。 初始化ArrayList可以指定大小也可以不指定,還可以用Collection的子類來初始化。

    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 = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

add(E e)方法會自動擴容

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

其中呼叫了grow函式,擴充最大數量為21萬左右

/**
 * 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
 */
    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();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;     
    }

Contains(Object o)方法呼叫了indexOf(Object o)

    public boolean contains(Object o) {
        return indexOf(o) >= 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&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;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;
    }

sort(Comparator<? super E> c)

    @Override
    @SuppressWarnings("unchecked")
    public void sort(Comparator<? super E> c) {
        final int expectedModCount = modCount;
        Arrays.sort((E[]) elementData, 0, size, c);
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
        modCount++;
    }

LinkedList

LinkedList 繼承了AbstractSequentialList(繼承了AbstractList實現了get、set、add、remove等)。size為連結串列的大小,first為第一個結點,last為最後一個結點。 聲明瞭Node結點儲存,儲存前一個和後一個結點。具體儲存的值在E item中。

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

add()函式呼叫了linkLast(e)

    public boolean add(E e) {
        linkLast(e);
        return true;
    }
    void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);   //構造e結點,前一個結點為原連結串列的last結點
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }