最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java LinkedList的實(shí)現(xiàn)原理圖文詳解

 更新時(shí)間:2019年01月11日 14:29:24   作者:qq_43193797  
今天小編就為大家分享一篇關(guān)于Java LinkedList的實(shí)現(xiàn)原理圖文詳解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧

一、概述

先來(lái)看看源碼中的這一段注釋,我們先嘗試從中提取一些信息:

Doubly-linked list implementation of the List and Deque interfaces. Implements all optional list operations, and permits all elements (including null).All of the operations perform as could be expected for a doubly-linked list. Operations that index into the list will traverse the list from the beginning or the end, whichever is closer to the specified index.Note that this implementation is not synchronized. If multiple threads access a linked list concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements; merely setting the value of an element is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the list.

從這段注釋中,我們可以得知 LinkedList 是通過(guò)一個(gè)雙向鏈表來(lái)實(shí)現(xiàn)的,它允許插入所有元素,包括 null,同時(shí),它是線程不同步的。如果對(duì)雙向鏈表這個(gè)數(shù)據(jù)結(jié)構(gòu)很熟悉的話,學(xué)習(xí)LinkedList 就沒(méi)什么難度了。下面是雙向鏈表的結(jié)構(gòu):

雙向鏈表每個(gè)結(jié)點(diǎn)除了數(shù)據(jù)域之外,還有一個(gè)前指針和后指針,分別指向前驅(qū)結(jié)點(diǎn)和后繼結(jié)點(diǎn)(如果有前驅(qū)/后繼的話)。另外,雙向鏈表還有一個(gè) first 指針,指向頭節(jié)點(diǎn),和 last 指針,指向尾節(jié)點(diǎn)。

二、屬性

接下來(lái)看一下 LinkedList 中的屬性:

//鏈表的節(jié)點(diǎn)個(gè)數(shù)
transient int size = 0;
//指向頭節(jié)點(diǎn)的指針
transient Node<E> first;
//指向尾節(jié)點(diǎn)的指針
transient Node<E> last;

LinkedList 的屬性非常少,就只有這些。通過(guò)這三個(gè)屬性,其實(shí)我們大概也可以猜測(cè)出它是怎么實(shí)現(xiàn)的了。

三、方法

1、結(jié)點(diǎn)結(jié)構(gòu)

Node 是在 LinkedList 里定義的一個(gè)靜態(tài)內(nèi)部類,它表示鏈表每個(gè)節(jié)點(diǎn)的結(jié)構(gòu),包括一個(gè)數(shù)據(jù)域 item,一個(gè)后置指針 next,一個(gè)前置指針 prev。

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;
 }
}

2、添加元素

對(duì)于鏈表這種數(shù)據(jù)結(jié)構(gòu)來(lái)說(shuō),添加元素的操作無(wú)非就是在表頭/表尾插入元素,又或者在指定位置插入元素。因?yàn)?LinkedList 有頭指針和尾指針,所以在表頭或表尾進(jìn)行插入元素只需要 O(1) 的時(shí)間,而在指定位置插入元素則需要先遍歷一下鏈表,所以復(fù)雜度為 O(n)。

在表頭添加元素的過(guò)程如下:

當(dāng)向表頭插入一個(gè)節(jié)點(diǎn)時(shí),很顯然當(dāng)前節(jié)點(diǎn)的前驅(qū)一定為 null,而后繼結(jié)點(diǎn)是 first 指針指向的節(jié)點(diǎn),當(dāng)然還要修改 first 指針指向新的頭節(jié)點(diǎn)。除此之外,原來(lái)的頭節(jié)點(diǎn)變成了第二個(gè)節(jié)點(diǎn),所以還要修改原來(lái)頭節(jié)點(diǎn)的前驅(qū)指針,使它指向表頭節(jié)點(diǎn),源碼的實(shí)現(xiàn)如下:

private void linkFirst(E e) {
 final Node<E> f = first;
 //當(dāng)前節(jié)點(diǎn)的前驅(qū)指向 null,后繼指針原來(lái)的頭節(jié)點(diǎn)
 final Node<E> newNode = new Node<>(null, e, f);
 //頭指針指向新的頭節(jié)點(diǎn)
 first = newNode;
 //如果原來(lái)有頭節(jié)點(diǎn),則更新原來(lái)節(jié)點(diǎn)的前驅(qū)指針,否則更新尾指針
 if (f == null)
 last = newNode;
 else
 f.prev = newNode;
 size++;
 modCount++;
}

在表尾添加元素跟在表頭添加元素大同小異,如圖所示

當(dāng)向表尾插入一個(gè)節(jié)點(diǎn)時(shí),很顯然當(dāng)前節(jié)點(diǎn)的后繼一定為 null,而前驅(qū)結(jié)點(diǎn)是 last指針指向的節(jié)點(diǎn),然后還要修改 last 指針指向新的尾節(jié)點(diǎn)。此外,還要修改原來(lái)尾節(jié)點(diǎn)的后繼指針,使它指向新的尾節(jié)點(diǎn),源碼的實(shí)現(xiàn)如下:

void linkLast(E e) {
 final Node<E> l = last;
 //當(dāng)前節(jié)點(diǎn)的前驅(qū)指向尾節(jié)點(diǎn),后繼指向 null
 final Node<E> newNode = new Node<>(l, e, null);
 //尾指針指向新的尾節(jié)點(diǎn)
 last = newNode;
 //如果原來(lái)有尾節(jié)點(diǎn),則更新原來(lái)節(jié)點(diǎn)的后繼指針,否則更新頭指針
 if (l == null)
 first = newNode;
 else
 l.next = newNode;
 size++;
 modCount++;
}

最后,在指定節(jié)點(diǎn)之前插入,如圖所示

當(dāng)向指定節(jié)點(diǎn)之前插入一個(gè)節(jié)點(diǎn)時(shí),當(dāng)前節(jié)點(diǎn)的后繼為指定節(jié)點(diǎn),而前驅(qū)結(jié)點(diǎn)為指定節(jié)點(diǎn)的前驅(qū)節(jié)點(diǎn)。此外,還要修改前驅(qū)節(jié)點(diǎn)的后繼為當(dāng)前節(jié)點(diǎn),以及后繼節(jié)點(diǎn)的前驅(qū)為當(dāng)前節(jié)點(diǎn),源碼的實(shí)現(xiàn)如下:

void linkBefore(E e, Node<E> succ) {
 // assert succ != null;
 //指定節(jié)點(diǎn)的前驅(qū)
 final Node<E> pred = succ.prev;
 //當(dāng)前節(jié)點(diǎn)的前驅(qū)為指點(diǎn)節(jié)點(diǎn)的前驅(qū),后繼為指定的節(jié)點(diǎn)
 final Node<E> newNode = new Node<>(pred, e, succ);
 //更新指定節(jié)點(diǎn)的前驅(qū)為當(dāng)前節(jié)點(diǎn)
 succ.prev = newNode;
 //更新前驅(qū)節(jié)點(diǎn)的后繼
 if (pred == null)
 first = newNode;
 else
 pred.next = newNode;
 size++;
 modCount++;
}

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接

相關(guān)文章

  • httpclient evict操作源碼解讀

    httpclient evict操作源碼解讀

    這篇文章主要為大家介紹了httpclient evict操作源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • IDEA 程序包不存在,找不到符號(hào)但是明明存在對(duì)應(yīng)的jar包(問(wèn)題分析及解決方案)

    IDEA 程序包不存在,找不到符號(hào)但是明明存在對(duì)應(yīng)的jar包(問(wèn)題分析及解決方案)

    這篇文章主要介紹了IDEA 程序包不存在,找不到符號(hào)但是明明存在對(duì)應(yīng)的jar包 的解決方案,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • java二分查找插入法

    java二分查找插入法

    當(dāng)你需要構(gòu)建一個(gè)大的有序隊(duì)列,用插入發(fā)太慢了,可以先用二分查找法,找到在隊(duì)列要插入的位置,把數(shù)后移一下,然后放進(jìn)去。比較效率,下面是java使用示例,需要的朋友可以參考下
    2014-03-03
  • Java中ThreadLocal?導(dǎo)致內(nèi)存?OOM?的原因分析

    Java中ThreadLocal?導(dǎo)致內(nèi)存?OOM?的原因分析

    這篇文章主要介紹了Java中ThreadLocal導(dǎo)致內(nèi)存OOM的原因分析,文章基于Java的相關(guān)內(nèi)容展開(kāi)ThreadLocal導(dǎo)致內(nèi)存OOM的原因分析,需要的小伙v阿布可以參考一下
    2022-05-05
  • java單例模式學(xué)習(xí)示例

    java單例模式學(xué)習(xí)示例

    java中單例模式是一種常見(jiàn)的設(shè)計(jì)模式,單例模式分三種:懶漢式單例、餓漢式單例、登記式單例三種,下面提供了單例模式的示例
    2014-01-01
  • Java的動(dòng)態(tài)代理和靜態(tài)代理及反射常用API詳解

    Java的動(dòng)態(tài)代理和靜態(tài)代理及反射常用API詳解

    這篇文章主要介紹了Java的動(dòng)態(tài)代理和靜態(tài)代理及反射常用API詳解,動(dòng)態(tài)代理是一種在運(yùn)行時(shí)動(dòng)態(tài)生成代理對(duì)象的技術(shù),它是一種設(shè)計(jì)模式,用于在不修改原始對(duì)象的情況下,通過(guò)代理對(duì)象來(lái)間接訪問(wèn)原始對(duì)象,并在訪問(wèn)前后執(zhí)行額外的操作,需要的朋友可以參考下
    2024-01-01
  • Java?9?中的模塊Module系統(tǒng)

    Java?9?中的模塊Module系統(tǒng)

    Java?9?引入的模塊是在Java包(package)的基礎(chǔ)上又引入的一個(gè)新的抽象層,基于package這一點(diǎn)很重要,這里需要強(qiáng)調(diào)一下,接下來(lái)通過(guò)本文給大家介紹Java?9?中的模塊Module系統(tǒng),感興趣的朋友一起看看吧
    2022-03-03
  • Mybatis/Mybatis-Plus駝峰式命名映射的實(shí)現(xiàn)

    Mybatis/Mybatis-Plus駝峰式命名映射的實(shí)現(xiàn)

    本文主要介紹了Mybatis-Plus駝峰式命名映射的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • SpringCloud項(xiàng)目集成Feign、Hystrix過(guò)程解析

    SpringCloud項(xiàng)目集成Feign、Hystrix過(guò)程解析

    這篇文章主要介紹了SpringCloud項(xiàng)目集成Feign、Hystrix過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Java基于logback?MessageConverter實(shí)現(xiàn)日志脫敏方案分析

    Java基于logback?MessageConverter實(shí)現(xiàn)日志脫敏方案分析

    本文介紹了一種日志脫敏方案,即基于logbackMessageConverter和正則匹配的方法,該方法的優(yōu)點(diǎn)是侵入性低,工作量少,只需修改xml配置文件,適用于老項(xiàng)目,感興趣的朋友跟隨小編一起看看吧
    2024-10-10

最新評(píng)論

石阡县| 阳春市| 吴旗县| 越西县| 德安县| 安图县| 宜州市| 当涂县| 西藏| 皮山县| 嵊泗县| 清原| 扎兰屯市| 那曲县| 清苑县| 诸暨市| 阳泉市| 咸丰县| 临澧县| 平果县| 德江县| 陇南市| 五寨县| 理塘县| 永丰县| 阿克苏市| 阿图什市| 崇左市| 长治市| 黄石市| 三明市| 柞水县| 桂阳县| 东乌珠穆沁旗| 弥勒县| 安顺市| 佛学| 通州市| 湾仔区| 襄城县| 丹棱县|