1. 程式人生 > >jdk1.6 1.7 1.8 LinkedList原始碼實現原理及區別

jdk1.6 1.7 1.8 LinkedList原始碼實現原理及區別

LinkedList(jdk1.6)

private transient Entry<E> header = new Entry<E>(null, null, null);

定義一個空的Entry物件作為頭結點,Entry是其內部定義的一個內部靜態類,結構如下:

private static class Entry<E> {
    E element;
    Entry<E> next;
    Entry<E> previous;

    Entry(E element, Entry<E> next, Entry<E> previous) {
        this
.element = element; this.next = next; this.previous = previous; } }

建構函式

public LinkedList() {
        header.next = header.previous = header;
    }

即把首結點尾結點都指向頭結點

 public E getFirst() {
    if (size==0)
        throw new NoSuchElementException();

    return header.next.element;
    }

獲取元素首節點,如果連結串列中沒有元素,會報NoSuchElementException錯誤。

 public E getLast()  {
    if (size==0)
        throw new NoSuchElementException();

    return header.previous.element;
}

獲取元素尾結點,同樣的,如果連結串列中沒有元素,會報NoSuchElementException錯誤。

public E removeFirst() {
    return remove(header.next);
}

刪除首結點,其內部是通過下面函式實現的

private E remove(Entry<E> e) {
    if (e == header)
        throw new NoSuchElementException();

        E result = e.element;
        e.previous.next = e.next;
        e.next.previous = e.previous;
        e.next = e.previous = null;
        e.element = null;
        size--;
        modCount++;
        return result;
    }

實現原理就是把要刪除結點的前一個結點的下一個節點指向要刪除結點的下一個節點,把要輸出結點的下一個節點的前結點指向要刪除結點的前一個結點,把刪除結點的相關成員置空,並返回刪除的元素值。

public E removeLast() {
    return remove(header.previous);
    }

刪除尾結點,原理如上。

public boolean remove(Object o) {
        if (o==null) {
            for (Entry<E> e = header.next; e != header; e = e.next) {
                if (e.element==null) {
                    remove(e);
                    return true;
                }
            }
        } else {
            for (Entry<E> e = header.next; e != header; e = e.next) {
                if (o.equals(e.element)) {
                    remove(e);
                    return true;
                }
            }
        }
        return false;
    }

刪除結點,遍歷到對應的結點刪除,刪除原理如上。

public E remove(int index) {
        return remove(entry(index));
    }

根索引值獲取對應Entry,刪除原理如上,entry函式的實現在下面會寫。

public void addFirst(E e) {
    addBefore(e, header.next);
}

新增首節點,其內部實現原理如下:

private Entry<E> addBefore(E e, Entry<E> entry) {
        Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);
        newEntry.previous.next = newEntry;
        newEntry.next.previous = newEntry;
        size++;
        modCount++;
        return newEntry;
    }

首先新建一個要新增的Entry,通過Entry的含參建構函式指定新Entry的next和prev結點,之後修改使新節點的prev結點的next結點指向自己,使新節點的next結點的prev結點指向自己,並返回新節點。

public void addLast(E e) {
    addBefore(e, header);
}

新增尾結點,原理如上。

public boolean add(E e) {
    addBefore(e, header);
        return true;
    }

新增結點,預設也是新增尾結點,原理如上。

public boolean contains(Object o) {
        return indexOf(o) != -1;
 }

其實現原理如下函式:

public int indexOf(Object o) {
        int index = 0;
        if (o==null) {
            for (Entry e = header.next; e != header; e = e.next) {
                if (e.element==null)
                    return index;
                index++;
            }
        } else {
            for (Entry e = header.next; e != header; e = e.next) {
                if (o.equals(e.element))
                    return index;
                index++;
            }
        }
        return -1;
}

就是從首節點開始向後遍歷,返回對應索引值,找不到則返回-1.

 public E get(int index) {
        return entry(index).element;
 }

獲取指定索引元素,實現原理如下函式:

 private Entry<E> entry(int index) {
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException("Index: "+index+
                                                ", Size: "+size);
        Entry<E> e = header;
        if (index < (size >> 1)) {
            for (int i = 0; i <= index; i++)
                e = e.next;
        } else {
            for (int i = size; i > index; i--)
                e = e.previous;
        }
        return e;
    }

如果索引值小於元素數量的一半,那麼久從前往後遍歷,如果索引值大於等於元素數量的一半,那麼從後往前遍歷。

 public E set(int index, E element) {
        Entry<E> e = entry(index);
        E oldVal = e.element;
        e.element = element;
        return oldVal;
    }

先通過索引獲取對應Entry,再修改元素值,並返回老元素值。

public void add(int index, E element) {
addBefore(element, (index==size ? header : entry(index)));
}

也是先根據索引值獲取對應Entry,並將元素新增到該Entry前。

 public E peek() {
        if (size==0)
            return null;
        return getFirst();
    }

獲取首元素,與getFirst()的區別是,如果當前連結串列中沒有元素,則返回null,而getFirst()會報錯。

 public E element() {
        return getFirst();
    }

與getFirst()相同

public E poll() {
        if (size==0)
            return null;
        return removeFirst();
    }

刪除首元素,與removeFirst()的區別是,如果當前連結串列中沒有元素,則返回null,而removeFirst會報錯。

public E remove() {
        return removeFirst();
    }

public boolean offer(E e) {
        return add(e);
    }

 public boolean offerFirst(E e) {
        addFirst(e);
        return true;
    }

public boolean offerLast(E e) {
        addLast(e);
        return true;
    }

public E peekFirst() {
        if (size==0)
            return null;
        return getFirst();
    }

public E peekLast() {
        if (size==0)
            return null;
        return getLast();
    }

public E pollFirst() {
        if (size==0)
            return null;
        return removeFirst();
    }
public E pollLast() {
        if (size==0)
            return null;
        return removeLast();
    }

public void push(E e) {
        addFirst(e);
    }

public E pop() {
        return removeFirst();
    }

這些函式都很簡單,都是複用之前的實現,就不一一說明了。

LinkedList(jdk1.7和jdk1.8實現是相同的無區別)

未完待續、、

相關推薦

jdk1.6 1.7 1.8 LinkedList原始碼實現原理區別

LinkedList(jdk1.6) private transient Entry<E> header = new Entry<E>(null, null, null); 定義一個空的Entry物件作為頭結點,Entry是其內部

HashMap原始碼實現原理底層結構

Java為資料結構中的對映定義了一個介面java.util.Map,此介面主要有四個常用的實現類,分別是HashMap、Hashtable、LinkedHashMap和TreeMap。 HashMap:HashMap是陣列+連結串列實現的,它根據鍵的hashCode值儲存資料,大多數情況下可

ArrayList和linkedList底層實現原理以及區別

ArrayList 先說說Arraylist,Arraylist是基於動態陣列實現的,所以查詢速度快,但是增刪操作的速度會比較慢,但是為什麼會這樣?我解釋一下動態陣列,基本就可以明白這個問題了。 先說說靜態陣列是怎麼來儲存資料的,當我們使用new來建立一個數組,實際上是在

paip jdk1 4 1 5 5 0 1 6 6 0 7 0 8 0特點比較與不同

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

jdk1.6,1.7,1.8解壓版無需安裝(64位)

jdk1.6,1.7,1.8解壓使用版64位無需安裝,歡迎下載連結:https://pan.baidu.com/s/1qG2CjTI4maF78zz8PPiWag 密碼:jj67也可以使用下面的連結下載安裝:1、java SE 1.6各個版本 jdk http://www.o

Linux環境PHP5.6升級7.1.8

tar.gz tar pan net regex brush bsp inux 以及 PHP7和HHVM比較PHP7的在真實場景的性能確實已經和HHVM相當, 在一些場景甚至超過了HHVM。HHVM的運維復雜, 是多線程模型, 這就代表著如果一個線程導致crash了, 那麽

1.5-1.6-1.7-1.8-線性時不變LTI系統

線性時不變系統 本文引自《數字訊號處理 【美】 Richad G. Lyons》 眾所周知,LTI系統官方定義。 線性系統的例子: 假設 y(n)= - x(n) / 2 輸出序列是輸入序列取反後的1/2 輸入x1 : 1Hz -------------------輸出:

1,2,3,4,5,678,9九個數分成三組,各個數字使用一次

前幾天找工作,筆試下面這道題: 把1,2,3,4,5,6,7,8,9共九個數分成三組構成排列a1a2a3,a4a5a6,a7a8a9,而且每個數字使用有且僅有一次,構成的排列之比為3:2:1,求輸出所有

JDK 1.8 LinkedList原始碼分析

概述 Collection是最基本的集合介面,一個Collection代表一組Object的集合,這些Object被稱作Collection的元素。Collection是一個介面,用以提供規範定義,不能被例項化使用。  1.Set(無序、不可重複)  Set集合

JDK(1.6,1.7,1.8,10,11)64位解壓版配置使用

JDK(1.6,1.7,1.8,10,11)64位解壓版配置使用 安裝jdk解壓版 下載jdk地址   連結: https://pan.baidu.com/s/1sm8O5dF 密碼: 86p4 將下載的javaSE(1.6,1.7,1.8,10,11其中一種)解壓

快速判斷一個數能否被1、2、3、4、5、678、9、10、11、12、13、17、19、23等整除的規律

快速判斷一個數能否被1、2、3、4、5、6、7、8、9、10、11、12、13、17、19、23等整除的規律總結 (1) 1與0的特性: 1是任何整數的約數,即對於任何整數a,總有1|a.        &nb

jdk 1.5 1.6 1.7 1.8 1.9的新特性詳解帶例子

1.5 1.自動裝箱與拆箱: 2.列舉(常用來設計單例模式) 3.靜態匯入 4.可變引數 5.內省 1.6 1.Web服務元資料 2.指令碼語言支援 3.JTable的排序和過濾 4.更簡單,更強大的JAX-WS 5.輕量級Http Serv

jdk1.6 升級到1.7的方法

1.首先安裝jdk1.7 2.在eclipse中新增jdk 3.修改環境變數 4.檢視jdk版本 5.重新啟動eclispe 6.修改配置檔案

輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,88個數字,則最小的4個數字是1,2,3,4,。

解題思路: 1、最簡單方法,先排序,再取前k個,時間複雜度O(NlogN) class Solution { public: vector<int> GetLeastNumbers

pixel和nexus設備安卓9.0/8.1/7.1.x/6.x WiFi和信號圖標出現叉x號或者感嘆號的消除辦 法

連接 glob spa 8.0 菜單 thread 打開 col 支持 在安卓9.0/8.1/8.0/7.1.2裏如何消除x號(在老一點點版本是感嘆號)呢? 1.首先開啟usb調試,然後用數據線連接電腦和手機。 2.然後解決好您的adb驅動問題,具體教程見:http://w

23.輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,88個數字,則最小的4個數字是1,2,3,4,。

題目:輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。 import java.util.ArrayList; public

java 1.7 1.8新特性

val row def jce arr app 線程安全 動態 adl 在JDK1.7的新特性方面主要有下面幾方面的增強:1.jdk7語法上1.1二進制變量的表示,支持將整數類型用二進制來表示,用0b開頭。1.2 Switch語句支持string類型1.3 Try-with

noip初賽整理1.6&1.7&1.9(進位制轉換&資訊編碼表示&原碼補碼反碼)

進位制轉換  基數與權         基數:某進位制計數制允許的基本數學符號的個數。一般而言,J進位制數的基數是J。         位權(權):...(無聊定義賊長)。如 11010 B 的權從高到低為16,8,4,2,1。 字尾字母          B:二進

1.7~1.8學習筆記

requests.request()構造一個請求,支撐以下各方法的基礎方法 requests.get()獲取HTML網頁的主要方法,對應於HTTP的GET requests.head()獲取HTML網頁頭資訊的方法,對應於HTTP的HEAD requests.post()向HTML網頁提