LinkedList 源码分析

LinkedList :双向链表结构, 
内部存在frist节点 和 last节点。通过改变 首节点和 尾节点的引用来实现新增和修改



有一个内部类:
	//节点类,内部包括前节点和后节点,和数据项
	// 构造的时候把前和后节点,数据项初始化
    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;
        }
    }
	
	//大小默认是0
	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 an empty list.
     */
    public LinkedList() {
    }

	
	 /**
     * Constructs an empty list.构造方法默认空
     */
    public LinkedList() {
    }
	
	    public boolean add(E e) {
        linkLast(e);
        return true;
    }
	
	// 新建一个node,前节点指向last节点,后节点为null。将新建node为尾节点last
    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 boolean remove(Object o) {
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }
	
	//按索引插入,根据索引大小 /2 确定向前遍历,还是向后遍历,得到要插入的node,将该node的前后节点和新节点改变
	public void add(int index, E element) {
        checkPositionIndex(index);

        if (index == size)
            linkLast(element);
        else
            linkBefore(element, node(index));
    }	
		
		
		
	    void linkBefore(E e, Node<E> succ) {
        // assert succ != null;
        final Node<E> pred = succ.prev;
        final Node<E> newNode = new Node<>(pred, e, succ);
        succ.prev = newNode;
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        size++;
        modCount++;
    }
	
	
	
	
	
	

 图如下:

 

 

posted @ 2017-08-22 17:19  K____K  阅读(174)  评论(0编辑  收藏  举报