1. 程式人生 > >Java原始碼閱讀之LinkedList

Java原始碼閱讀之LinkedList

Summary:

  • public class LinkedList<E>  extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable
  • LinkedList通過連結串列結構實現的,物件中存有一個首一個尾引用;
  • 本類也提供了一些類似隨機操作的方法。如get(index),但是這些方法都是是偽隨機的!!

Fields:

transient int size = 0; //當前儲存的資料的個數
transient Node<E> first;
transient Node<E> last;

Constructor:

//預設構造空表
public LinkedList() {
}

getXX():

public E getFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return f.item;
}
public E getLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return l.item;
}

addXX():

public void addFirst(E e) {
        linkFirst(e);
}
public boolean add(E e) {
        linkLast(e);
        return true;
}
public void addLast(E e) {
        linkLast(e);
}

removeXX():

public E removeFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return unlinkFirst(f);
}
public E removeLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return unlinkLast(l);
 }
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;
}

indexOf():

public boolean contains(Object o) {
        return indexOf(o) != -1;
}
//從first向last方向一個一個比較,最差O(n)
public int indexOf(Object o) {
        int index = 0;
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null)
                    return index;
                index++;
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item))
                    return index;
                index++;
            }
        }
        return -1;
}

模擬索引的隨機操作

public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
}
public E set(int index, E element) {
        checkElementIndex(index);
        Node<E> x = node(index);
        E oldVal = x.item;
        x.item = element;
        return oldVal;
}
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));
}

//下面方法是上面方法都會使用的一個方法,根據index返回對應的節點
//從後往前或者從前往後移動min(index,size-index)個位置得到Node
Node<E> node(int index) {
        // assert isElementIndex(index);
        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;
        }
}


LinkedList底層實現

linkFirst()

//將元素插入連結串列的第一個位置處
private void linkFirst(E e) {
        final Node<E> f = first;
        final Node<E> newNode = new Node<>(null, e, f);
        first = newNode;
        if (f == null)
            last = newNode;
        else
            f.prev = newNode;
        size++;
        modCount++;
}

linkLast()

//將元素插入到連結串列的末尾
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++;
}

unlinkFirst()

//刪掉第一個節點的資料
private E unlinkFirst(Node<E> f) {
        // assert f == first && f != null;
        final E element = f.item;
        final Node<E> 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;
}

unlinkLast()

//刪掉最後一個節點的資料
private E unlinkLast(Node<E> l) {
        // assert l == last && l != null;
        final E element = l.item;
        final Node<E> 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;
}

unlink():

//刪掉指定節點
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;
}

內部類

//擁有前繼和後繼引用
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;
        }
}


相關推薦

Java原始碼閱讀LinkedList

Summary: public class LinkedList<E>  extends AbstractSequentialList<E> implements List&

JAVA原始碼閱讀LinkedList基於JDK1.8

LinkedList是另一個實現List介面的集合實現類,他的主要特點和ArrayList相比是佔用空間小,插入/刪除/修改塊,查詢較慢,是一個雙向連結串列的資料結構,既可以當成集合來使用,還可以當成佇列Queue(雙向佇列),而且還可以做stack棧來使用;接下來一起來看下

JAVA原始碼閱讀java.util—List

List List被宣告為一個介面,程式碼量很少,只聲明瞭方法。 public interface List<E> extends Collection<E> { int size(); boolean isEmpty(); boo

jdk原始碼閱讀LinkedList

和ArrayList相似,LinkedList也是實現了List介面,但是LinkedList是用連結串列實現的,而ArrayList是用陣列實現的。兩者的優缺點基本就是連結串列和陣列的優缺點。 先看LinkedList宣告 public class LinkedList<E>

java原始碼閱讀java.util.Objects

之所以寫這篇文章,是因為工作中接觸到一個開源專案程式碼,而這個開原始碼使用到了這個類。同時如果不是前面的包名java.util,都很容易看錯成java超類java.lang.Object。 java.util.Objects是java1.7新增的一個類。下面這篇文章將基於1

java原始碼閱讀Spliterator

Spliterator是java 8才開始提供的一個迭代器實現,從名稱可以看出來,Spliterator是一個可分割的迭代器,用來分割和迭代給定源的元素,這裡的源可以是collection,array和io等。 spliterator的特別之處在於,它可以通過

Java原始碼閱讀PriorityBlockingQueue

Summary: public class PriorityBlockingQueue<E> extends AbstractQueue<E> implements Bloc

Java進階----LinkedList原始碼分析

// 什麼都沒做,是一個空實現 public LinkedList() { } public LinkedList(Collection<? extends E> c) { this(); addAll(c); }

Java集合類原始碼閱讀AbstractCollection

private static <T> T[] finishToArray(T[] r, Iterator<?> it) { int i = r.length; while (it.hasNext()) { int cap = r.

[kafka掃盲]--(5)kafka原始碼閱讀模型物件--(1)ProducerRecord.java

Author:趙志乾 Date:2018-10-21 Declaration:All Right Reserved!!! ProducerRecord.java 該類的例項用於存放生產者向kafka叢集傳送的單條訊息記錄。其內容如下,共包含6個屬性欄位。其中的topic欄

java原始碼閱讀介面篇java.util.Collection

java.util.Collection是個介面,很容易和工具類java.util.Collections弄混淆。今天我就抽絲剝繭來研究一下這個介面。 這裡我基於JDK1.7.0_80的Collections介面進行研究,以避免JDK1.8引入的StreamAPI和函數語言

Java重要類LinkedList

collect div ext mage array 鏈表結構 java封裝 大致 ont 一、ArrayList與LinkedList 基本概念:List是一個接口,Arraylist和LinkedList是它的兩個實現類,只是實現的方式不一樣。我在“單鏈表java實現”

java集合類LinkedList詳解

list詳解 兩種 由於 list接口 add 不為 sel 結點 ESS 一、LinkedList簡介 由於LinkedList是一個實現了Deque的雙端隊列,所以LinkedList既可以當做Queue,又可以當做Stack,在將LinkedList當做Stack時,

Promise原始碼閱讀建構函式+then過程

前言 Promise是非同步程式設計的一種方案,ES6規範中將其寫入規範標準中,統一了用法。 考慮到瀏覽器的相容性,Vue專案中使用promise,就具體閱讀promise原始碼,看看內部的具體實現。 具體分析 通過具體例項來閱讀promise原始碼的實現,例項如下: new

java原始碼解讀HashMap

1:首先下載openjdk(http://pan.baidu.com/s/1dFMZXg1),把原始碼匯入eclipse,以便看到jdk原始碼            Windows-Prefe

Netty 原始碼閱讀初始環境搭建

推薦 netty 系列原始碼解析合集 http://www.iocoder.cn/Netty/Netty-collection/?aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3R6c18xMDQxMjE4MTI5L2FydGljbGUvZGV0YWlscy83OD

jdk原始碼閱讀——arraylist

首先看一下他的建構函式: public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } 其實arraylist還有其他的建構函式,可以指定陣列的長度,這裡先從最基本的入

netty原始碼閱讀效能優化工具類Recycle異執行緒獲取物件

在這篇《netty原始碼閱讀之效能優化工具類之Recycler獲取物件》文章裡面,我們還有一個scavenge()方法沒有解析,也就是在別的執行緒裡面回收物件。下面我們開始介紹,從這個方法開始進入: boolean scavenge() { // con

JAVA原始碼分析HashMap

前言 從事了好長時間的開發工作,平時只注重業務程式碼的開發,而忽略了java本身一些基礎,所以從現在開始閱讀以下jdk的原始碼,首先從集合開始吧!這一篇先看下HashMap的原始碼。 java集合架構   &nbs

我的原始碼閱讀路:redux原始碼剖析

前言 用過react的小夥伴對redux其實並不陌生,基本大多數的React應用用到它。一般大家用redux的時候基本都不會單獨去使用它,而是配合react-redux一起去使用。剛學習redux的時候很容易弄混淆redux和react-redux,以為他倆是同一個