溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

java中LinkedList有什么用

發(fā)布時(shí)間:2021-06-18 16:44:29 來(lái)源:億速云 閱讀:184 作者:Leah 欄目:大數(shù)據(jù)

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)java中LinkedList有什么用,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

整體架構(gòu)

底層數(shù)據(jù)結(jié)構(gòu)是一個(gè)雙向鏈表、適用于有順序迭代的場(chǎng)景

java中LinkedList有什么用

first:頭節(jié)點(diǎn)
last:尾節(jié)點(diǎn)
當(dāng)鏈表為空時(shí),last、first都是同一個(gè)節(jié)點(diǎn),前后都指向null
因?yàn)槭请p向鏈表,只要機(jī)器內(nèi)存足夠強(qiáng)大,是沒(méi)有大小限制的
node有是三個(gè)屬性:prev、next、item

private static class Node<E> {
    E item;// 節(jié)點(diǎn)值
    Node<E> next; // 指向的下一個(gè)節(jié)點(diǎn)
    Node<E> prev; // 指向的前一個(gè)節(jié)點(diǎn)

    // 初始化參數(shù)順序分別是:前一個(gè)節(jié)點(diǎn)、本身節(jié)點(diǎn)值、后一個(gè)節(jié)點(diǎn)
    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

源碼解析

一、新增、刪除

頭部新增:addFirst

// 從頭部追加
private void linkFirst(E e) {
    // 頭節(jié)點(diǎn)賦值給臨時(shí)變量
    final Node<E> f = first;
    // 新建節(jié)點(diǎn),前一個(gè)節(jié)點(diǎn)指向null,e 是新建節(jié)點(diǎn),f 是新建節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn),目前值是頭節(jié)點(diǎn)的值
    final Node<E> newNode = new Node<>(null, e, f);
    // 新建節(jié)點(diǎn)成為頭節(jié)點(diǎn)
    first = newNode;
    // 頭節(jié)點(diǎn)為空,就是鏈表為空,頭尾節(jié)點(diǎn)是一個(gè)節(jié)點(diǎn)
    if (f == null)
        last = newNode;
    //上一個(gè)頭節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)指向當(dāng)前節(jié)點(diǎn)
    else
        f.prev = newNode;
    size++;
    modCount++;
}

尾部新增:add

// 從尾部開始追加節(jié)點(diǎn)
void linkLast(E e) {
    // 把尾節(jié)點(diǎn)數(shù)據(jù)暫存
    final Node<E> l = last;
    // 新建新的節(jié)點(diǎn),初始化入?yún)⒑x:
    // l 是新節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn),當(dāng)前值是尾節(jié)點(diǎn)值
    // e 表示當(dāng)前新增節(jié)點(diǎn),當(dāng)前新增節(jié)點(diǎn)后一個(gè)節(jié)點(diǎn)是 null
    final Node<E> newNode = new Node<>(l, e, null);
    // 新建節(jié)點(diǎn)追加到尾部
    last = newNode;
    //如果鏈表為空(l 是尾節(jié)點(diǎn),尾節(jié)點(diǎn)為空,鏈表即空),頭部和尾部是同一個(gè)節(jié)點(diǎn),都是新建的節(jié)點(diǎn)
    if (l == null)
        first = newNode;![圖片描述](//img.mukewang.com/5d5fc69600013e4803600240.gif)
    //否則把前尾節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn),指向當(dāng)前尾節(jié)點(diǎn)。
    else
        l.next = newNode;
    //大小和版本更改
    size++;
    modCount++;
}

java中LinkedList有什么用

刪除
與新增類似、可以頭部刪除unlinkFirst、可以尾部刪除unlinkLast

//從頭刪除節(jié)點(diǎn) f 是鏈表頭節(jié)點(diǎn)
private E unlinkFirst(Node<E> f) {
    // 拿出頭節(jié)點(diǎn)的值,作為方法的返回值
    final E element = f.item;
    // 拿出頭節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)
    final Node<E> next = f.next;
    //幫助 GC 回收頭節(jié)點(diǎn)    f.item = null;
    f.next = null;
    // 頭節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)成為頭節(jié)點(diǎn)
    first = next;
    //如果 next 為空,表明鏈表為空
    if (next == null)
        last = null;
    //鏈表不為空,頭節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)指向 null
    else
        next.prev = null;
    //修改鏈表大小和版本
    size--;
    modCount++;
    return element;
}

查詢
LinkedList采用二分法進(jìn)行循環(huán)查詢(平時(shí)可借鑒)

// 根據(jù)鏈表索引位置查詢節(jié)點(diǎn)
Node<E> node(int index) {
    // 如果 index 處于隊(duì)列的前半部分,從頭開始找,size >> 1 是 size 除以 2 的意思。
    if (index < (size >> 1)) {
        Node<E> x = first;
        // 直到 for 循環(huán)到 index 的前一個(gè) node 停止
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    } else {// 如果 index 處于隊(duì)列的后半部分,從尾開始找
        Node<E> x = last;
        // 直到 for 循環(huán)到 index 的后一個(gè) node 停止
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
}

二、迭代器

ListIterator:提供了向前、向后的迭代方式

// 雙向迭代器
private class ListItr implements ListIterator<E> {
    private Node<E> lastReturned;//上一次執(zhí)行 next() 或者 previos() 方法時(shí)的節(jié)點(diǎn)位置
    private Node<E> next;//下一個(gè)節(jié)點(diǎn)
    private int nextIndex;//下一個(gè)節(jié)點(diǎn)的位置
    //expectedModCount:期望版本號(hào);modCount:目前最新版本號(hào)
    private int expectedModCount = modCount;
    …………
}

從頭到尾:

// 判斷還有沒(méi)有下一個(gè)元素
public boolean hasNext() {
    return nextIndex < size;// 下一個(gè)節(jié)點(diǎn)的索引小于鏈表的大小,就有
}

// 取下一個(gè)元素
public E next() {
    //檢查期望版本號(hào)有無(wú)發(fā)生變化
    checkForComodification();
    if (!hasNext())//再次檢查
        throw new NoSuchElementException();
    // next 是當(dāng)前節(jié)點(diǎn),在上一次執(zhí)行 next() 方法時(shí)被賦值的。
    // 第一次執(zhí)行時(shí),是在初始化迭代器的時(shí)候,next 被賦值的
    lastReturned = next;
    // next 是下一個(gè)節(jié)點(diǎn)了,為下次迭代做準(zhǔn)備
    next = next.next;
    nextIndex++;
    return lastReturned.item;
}

從尾到頭:

// 如果上次節(jié)點(diǎn)索引位置大于 0,就還有節(jié)點(diǎn)可以迭代
public boolean hasPrevious() {
    return nextIndex > 0;
}
// 取前一個(gè)節(jié)點(diǎn)
public E previous() {
    checkForComodification();
    if (!hasPrevious())
        throw new NoSuchElementException();
    // next 為空?qǐng)鼍埃?:說(shuō)明是第一次迭代,取尾節(jié)點(diǎn)(last);2:上一次操作把尾節(jié)點(diǎn)刪除掉了
    // next 不為空?qǐng)鼍埃赫f(shuō)明已經(jīng)發(fā)生過(guò)迭代了,直接取前一個(gè)節(jié)點(diǎn)即可(next.prev)    lastReturned = next = (next == null) ? last : next.prev;
    // 索引位置變化
    nextIndex--;
    return lastReturned.item;
}

刪除:

public void remove() {
    checkForComodification();
    // lastReturned 是本次迭代需要?jiǎng)h除的值,分以下空和非空兩種情況:
    // lastReturned 為空,說(shuō)明調(diào)用者沒(méi)有主動(dòng)執(zhí)行過(guò) next() 或者 previos(),直接報(bào)錯(cuò)
    // lastReturned 不為空,是在上次執(zhí)行 next() 或者 previos()方法時(shí)賦的值
    if (lastReturned == null)
        throw new IllegalStateException();
    Node<E> lastNext = lastReturned.next;
    //刪除當(dāng)前節(jié)點(diǎn)
    unlink(lastReturned);
    // next == lastReturned 的場(chǎng)景分析:從尾到頭遞歸順序,并且是第一次迭代,并且要?jiǎng)h除最后一個(gè)元素的情況下
    // 這種情況下,previous() 方法里面設(shè)置了 lastReturned = next = last,所以 next 和 lastReturned會(huì)相等
    if (next == lastReturned)
        // 這時(shí)候 lastReturned 是尾節(jié)點(diǎn),lastNext 是 null,所以 next 也是 null,這樣在 previous() 執(zhí)行時(shí),發(fā)現(xiàn) next 是 null,就會(huì)把尾節(jié)點(diǎn)賦值給 next
        next = lastNext;
    else
        nextIndex--;
    lastReturned = null;
    expectedModCount++;
}

上述就是小編為大家分享的java中LinkedList有什么用了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI