ArrayList和LinkedList學習

#ArrayList和LinkedList學習 ##1.ArrayListnode

###1.1源碼分析 //默認數組容量即長度爲10 private static final int DEFAULT_CAPACITY = 10;數組

//存儲對象數組
	transient Object[] elementData; 
	
	//數組長度
	private int size;

	//最大數組長度
	private static final int MAX_ARRAY_SIZE = 	Integer.MAX_VALUE - 8;

	//爲空的對象數組
	private static final Object[] 	DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

	//添加數據
	public boolean add(E e) {
	 	//檢驗數組長度
    	ensureCapacityInternal(size + 1);         			elementData[size++] = e;
    	return true;
	}
	
	private void ensureCapacityInternal(int minCapacity) 
	{
	//若是對象數組爲空
    if (elementData == 	DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
    //容量爲默認容量和當前數組容量的最大值
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    //確保當前容量是否須要擴容
    ensureExplicitCapacity(minCapacity);
    
    }
    
    
     private void ensureExplicitCapacity(int minCapacity) {
    //操做數加一
    modCount++;
   //若是當前數組容量大於存儲對象數組大小
    if (minCapacity - elementData.length > 0)
    	//擴展容量
        grow(minCapacity);
}
 

//擴容 
private void grow(int minCapacity) {
    
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
    	//確認新的數組長度
        newCapacity = hugeCapacity(minCapacity);
    //進行拷貝操做
    elementData = Arrays.copyOf(elementData, newCapacity);
}

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) 
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
}

// 根據下標獲取
public E get(int index) {
	//檢驗下標是否超過數組長度
    rangeCheck(index);
    return elementData(index);
}

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

##2.LinkedList源碼分析

###2.1源碼分析學習

//鏈表長度
	transient int size = 0;
	
	//添加數據
	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);
    last = newNode;
    if (l == null)
   		//表示鏈表爲空
        first = newNode;
    else
    	//鏈表不爲空,則當前尾節點的下一節點爲新節點
        l.next = newNode;
    //鏈表長度加一
    size++;
    //操做數加一
    modCount++;
    }
    
    //刪除數據
    public E remove(int index) {
    //檢驗下標
    checkElementIndex(index);
    return unlink(node(index));
	}
    
    //根據下標得到節點
    Node<E> node(int index) {
	
	// >>:右移運算符,size >> 1,至關於size除以2的1次方
    if (index < (size >> 1)) {
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    } else {
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
	}
    
    
    
    //刪除某個節點
    E unlink(Node<E> x) {
    
    // assert x != null;
    final E element = x.item;
    final Node<E> next = x.next;
    final Node<E> prev = x.prev;

    if (prev == null) {
        first = next;
    } else {
        prev.next = next;
        x.prev = null;
    }

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

    x.item = null;
    //鏈表長度減一
    size--;
    //操做數加一
    modCount++;
    
    return element;
	}

##3.比較指針

當讀取數據時,採用ArrayList更快,由於是根據下標訪問,時間爲O(1),而code

LinkedList會先遍歷鏈表,才能找到下標表明的節點,時間爲O(m)。對象

當寫入,刪除數據時,採用LinkedList更快,由於他經過修改頭尾指針指向的對象,便可ci

完成添加,或者刪除。而ArrayList則須要進行數組的拷貝。element

相關文章
相關標籤/搜索