Java類集架構之LinkedList源碼剖析

來源:互聯網
上載者:User

標籤:

LinkedList

LinkedList基於雙向迴圈鏈表實現。也可以被當做堆棧,隊列或雙端隊列進行操作。非安全執行緒。下面直接貼ArrayList的Java實現(只貼了部分代碼),來源JDK1.8.0_25/src.zip。

 

    /**     * ****雙向鏈表對應的資料結構*********     * 包含:節點值item     *     前驅  pre     *     後繼next         * @param      */    private static class Node {        E item;        Node next;        Node prev;        //構造方法參數順序:前驅  節點值 後繼        Node(Node prev, E element, Node next) {            this.item = element;            this.next = next;            this.prev = prev;        }    }

 

public class LinkedList extends AbstractSequentialList implements List, Deque, Cloneable, java.io.Serializable{//元素個數    transient int size = 0;     //指向第一個節點    transient Node first;    //指向最後一個節點    transient Node last;    //構造方法1--構造一個空列表    public LinkedList() {}    //構造方法2--構造一個包含指定collection中元素的列表,按collection的迭代器返回的順序排列    public LinkedList(Collection c) {        this();        addAll(c);    }        //將e插入到鏈表第一個位置前面,注意可能修改last和first    private void linkFirst(E e) {        final Node f = first;        final Node newNode = new Node<>(null, e, f);//Node(前驅,元素,後繼)        first = newNode;        if (f == null)            last = newNode;//插入前為空白則last為其本身        else            f.prev = newNode;//若不為空白則頭結點前驅指向newnode        size++;        modCount++;    }    //將e插入到鏈表最後一個元素的後面    void linkLast(E e) {        final Node l = last;        final Node newNode = new Node<>(l, e, null);        last = newNode;        if (l == null)            first = newNode;        else            l.next = newNode;        size++;        modCount++;    }    //在節點succ前插入元素為e的節點    void linkBefore(E e, Node succ) {        // assert succ != null;        final Node pred = succ.prev;        final Node newNode = new Node<>(pred, e, succ);        succ.prev = newNode;        if (pred == null)            first = newNode;        else            pred.next = newNode;        size++;        modCount++;    }    //去除鏈表第一個元素    private E unlinkFirst(Node f) {        // assert f == first && f != null;        final E element = f.item;        final Node next = f.next;        f.item = null;        f.next = null; // help GC        first = next;        if (next == null)            last = null;        else            next.prev = null;        size--;        modCount++;        return element;    }    //去除鏈表最後一個元素    private E unlinkLast(Node l) {        // assert l == last && l != null;        final E element = l.item;        final Node prev = l.prev;        l.item = null;        l.prev = null; // help GC        last = prev;        if (prev == null)            first = null;        else            prev.next = null;        size--;        modCount++;        return element;    }    //刪除節點x    E unlink(Node x) {        // assert x != null;        final E element = x.item;        final Node next = x.next;        final Node 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;    }    //擷取第一個元素,若為空白,拋出異常    public E getFirst() {        final Node f = first;        if (f == null)            throw new NoSuchElementException();        return f.item;    }    //擷取第一個元素,若為空白,拋出異常    public E getLast() {        final Node l = last;        if (l == null)            throw new NoSuchElementException();        return l.item;    }    //去除第一個元素    public E removeFirst() {        final Node f = first;        if (f == null)            throw new NoSuchElementException();        return unlinkFirst(f);    }    //去除最後一個元素    public E removeLast() {        final Node l = last;        if (l == null)            throw new NoSuchElementException();        return unlinkLast(l);    }    //將元素e添加為鏈表第一個元素    public void addFirst(E e) {        linkFirst(e);    }    public void addLast(E e) {        linkLast(e);    }    public boolean contains(Object o) {        return indexOf(o) != -1;    }    public int size() {        return size;    }    public boolean add(E e) {        linkLast(e);//添加到最後面        return true;    }        //可以去除null元素,從鏈表開始尋找指定元素o    public boolean remove(Object o) {        if (o == null) {            for (Node x = first; x != null; x = x.next) {                if (x.item == null) {                    unlink(x);                    return true;                }            }        } else {            for (Node x = first; x != null; x = x.next) {                if (o.equals(x.item)) {                    unlink(x);                    return true;                }            }        }        return false;    }    //從LinkedList的末尾開始,將集合c添加到LinkedList中    public boolean addAll(Collection c) {        return addAll(size, c);    }    //從LinkedList的index開始,將集合c中的元素添加到LinkedList中    public boolean addAll(int index, Collection c) {        checkPositionIndex(index);        Object[] a = c.toArray();        int numNew = a.length;        if (numNew == 0)//集合c為空白,返回false            return false;        Node 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 newNode = new Node<>(pred, e, null);            if (pred == null)                first = newNode;//時刻注意修改first和last            else                pred.next = newNode;            pred = newNode;        }        if (succ == null) {            last = pred;        } else {            pred.next = succ;            succ.prev = pred;        }        size += numNew;//添加後鏈表大小        modCount++;        return true;    }    //清空雙向鏈表    public void clear() {        for (Node x = first; x != null; ) {            Node next = x.next;            x.item = null;            x.next = null;            x.prev = null;            x = next;        }        first = last = null;        size = 0;        modCount++;    }    // Positional Access Operations    //擷取指定位置元素    public E get(int index) {        checkElementIndex(index);        return node(index).item;    }    //設定指定位置元素值,並返回原來的值    public E set(int index, E element) {        checkElementIndex(index);        Node x = node(index);        E oldVal = x.item;        x.item = element;        return oldVal;    }    //-----在index前添加元素值為element的節點----    public void add(int index, E element) {        checkPositionIndex(index);        if (index == size)            linkLast(element);        else            linkBefore(element, node(index));    }    //刪除指定位置節點    public E remove(int index) {        checkElementIndex(index);        return unlink(node(index));    }    private boolean isElementIndex(int index) {        return index >= 0 && index < size;    }    private boolean isPositionIndex(int index) {        return index >= 0 && index <= size;    }    private String outOfBoundsMsg(int index) {        return "Index: "+index+", Size: "+size;    }    private void checkElementIndex(int index) {        if (!isElementIndex(index))            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));    }    private void checkPositionIndex(int index) {        if (!isPositionIndex(index))            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));    }    //以前版本是entry,擷取指定位置的節點    Node node(int index) {        // assert isElementIndex(index);    //若要尋找位置小於雙向鏈表的一半,則從前往後尋找,否則從後往前尋找,提高尋找效率        if (index < (size >> 1)) {            Node x = first;            for (int i = 0; i < index; i++)                x = x.next;            return x;        } else {            Node x = last;            for (int i = size - 1; i > index; i--)                x = x.prev;            return x;        }    }    // Search Operations    //從前往後尋找,傳回值為o的節點位置,若不存在返回-1,可尋找null位置    //尋找的都是第一次出現的    public int indexOf(Object o) {        int index = 0;        if (o == null) {            for (Node x = first; x != null; x = x.next) {                if (x.item == null)                    return index;                index++;            }        } else {            for (Node x = first; x != null; x = x.next) {                if (o.equals(x.item))                    return index;                index++;            }        }        return -1;    }    //從後往前尋找,傳回值為o的節點位置,若不存在返回-1,可尋找null位置    //尋找的都是第一次出現的    public int lastIndexOf(Object o) {        int index = size;        if (o == null) {            for (Node x = last; x != null; x = x.prev) {                index--;                if (x.item == null)                    return index;            }        } else {            for (Node x = last; x != null; x = x.prev) {                index--;                if (o.equals(x.item))                    return index;            }        }        return -1;    }    /*******作為隊列使用的操作 Queue operations.************/        //返回第一個節點元素,若為空白返回null,擷取但不移除(不出隊)    public E peek() {        final Node f = first;        return (f == null) ? null : f.item;    }    //返回第一個節點元素,若為空白拋出異常,相當於出隊    public E element() {        return getFirst();    }    //出隊,擷取並移除表頭    public E poll() {        final Node f = first;        return (f == null) ? null : unlinkFirst(f);    }    public E remove() {        return removeFirst();    }    //入隊,添加到表尾    public boolean offer(E e) {        return add(e);    }    /**** Deque operations****/            public boolean offerFirst(E e) {        addFirst(e);        return true;    }    public boolean offerLast(E e) {        addLast(e);        return true;    }    public E peekFirst() {        final Node f = first;        return (f == null) ? null : f.item;     }    public E peekLast() {        final Node l = last;        return (l == null) ? null : l.item;    }    public E pollFirst() {        final Node f = first;        return (f == null) ? null : unlinkFirst(f);    }    public E pollLast() {        final Node l = last;        return (l == null) ? null : unlinkLast(l);    }    public void push(E e) {        addFirst(e);    }    public E pop() {        return removeFirst();    }    public boolean removeFirstOccurrence(Object o) {        return remove(o);    }    //去除最後一次出現的指定節點,從後往前尋找的第一個節點去除即可  可為null    public boolean removeLastOccurrence(Object o) {        if (o == null) {            for (Node x = last; x != null; x = x.prev) {                if (x.item == null) {                    unlink(x);                    return true;                }            }        } else {            for (Node x = last; x != null; x = x.prev) {                if (o.equals(x.item)) {                    unlink(x);                    return true;                }            }        }        return false;    }    //返回index到末尾的全部節點對應的ListIterator對象    public ListIterator listIterator(int index) {        checkPositionIndex(index);        return new ListItr(index);    }        //List迭代器    private class ListItr implements ListIterator {        private Node lastReturned;//上一次返回的節點        private Node next;//下一個節點        private int nextIndex;//下一個節點索引        //期望的改變計數,用來實現fail-fast機制        private int expectedModCount = modCount;        ListItr(int index) {            // assert isPositionIndex(index);            next = (index == size) ? null : node(index);            nextIndex = index;        }
    public Object clone() {        LinkedList clone = superClone();        // Put clone into "virgin" state        clone.first = clone.last = null;        clone.size = 0;        clone.modCount = 0;        // Initialize clone with our elements        for (Node x = first; x != null; x = x.next)            clone.add(x.item);        return clone;    }


建構函式:

 

LinkedList構造方法有2種,一個是無參構造方法,建立一個空的鏈表(頭結點null) 另一個是先建立一個空鏈表,再調用addAll(c)用c中元素初始化。

說明:

LinkedList基於雙向迴圈鏈表實現的,不存在容量不足和擴容,但是插入和刪除的效率高。在插入一個結點時,建立一個node對象,找到插入節點的位置,改變前驅和後繼。刪除一個結點時,改變刪除節點的前驅節點的後繼和後繼節點的前驅,不需要移動元素。

LinkedList容許元素為null,在尋找和刪除某元素時,都區分null和非null

LinkedList實現了棧和隊列的操作,如push() pop() 等方法,為了區分不同的操作,很多方法名不一樣,但是功能是一樣的。

Java類集架構之LinkedList源碼剖析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.