【集合框架LinkedList底層添加元素機制】

在 Java 集合框架中,LinkedListArrayList 是兩種截然不同的線性表實現。如果說 ArrayList 像一個可以伸縮的“盒子陣列”,那么 LinkedList 就像一條由“節點”串聯而成的“雙向鏈條”。

今天,我們將深入 LinkedList 的源碼,一步步剖析它作為雙向鏈表的精妙設計。通過這篇解析,你將徹底明白 LinkedList 是如何通過 firstlast 指針,高效地管理元素的。


一、LinkedList?的誕生:空鏈的起點

當我們執行 new LinkedList<>() 時,LinkedList 在底層做了什么?

// 代碼塊
LinkedList<String> list = new LinkedList<>();

核心真相:此時,LinkedList 并沒有創建任何節點。它只初始化了兩個至關重要的指針(引用)

  1. first:指向鏈表的頭節點(第一個節點)。
  2. last:指向鏈表的尾節點(最后一個節點)。

在創建之初,鏈表為空,因此 firstlast 都被初始化為 null

// 代碼塊
// LinkedList 源碼中的定義
transient Node<E> first;
transient Node<E> last;


二、成長的第一步:添加第一個元素

當我們調用 list.add("Hello") 時,發生了什么?

  1. 創建新節點LinkedList?會創建一個全新的?Node?對象。這個節點的結構非常簡單,包含三部分:
    • item:存儲元素?"Hello"
    • next:指向下一個節點的引用。
    • prev:指向前一個節點的引用。
  2. 初始化節點:由于這是第一個節點,它的?prev?和?next?都指向?null
  3. 更新指針first?和?last?這兩個指針,都指向這個新創建的節點。因為此時,這個節點既是頭節點,也是尾節點。
// 代碼塊
// Node 類的定義 (簡化)
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;}
}

此時,LinkedList 的內部結構如下圖所示:


三、鏈的延伸:添加第二個元素

當我們調用 list.add("World") 時,鏈表開始延伸。

  1. 創建新節點:創建一個新的?Node?對象,存儲元素?"World"
  2. 建立連接
    • 前向連接:第一個節點(當前的?last)的?next?指針,將指向這個新節點。
    • 后向連接:新節點的?prev?指針,將指向第一個節點。
  3. 更新尾指針last?指針不再指向第一個節點,而是更新為指向這個新創建的節點first?指針保持不變,仍然指向第一個節點。

此時,鏈表的結構變成了:

first -> [item: "Hello", prev: null, next: ->] <-> [item: "World", prev: <-, next: null] <- last

四、雙向鏈表的魅力:高效的操作

LinkedList 的雙向鏈表結構賦予了它獨特的優勢:

1.?頭尾操作的極致效率

  • addFirst()?/?addLast():由于?first?和?last?指針的存在,向鏈表頭部或尾部添加元素的時間復雜度都是?O(1)
  • removeFirst()?/?removeLast():同理,刪除頭尾元素也是?O(1)

2.?中間插入/刪除的“局部性”

  • 在鏈表中間插入或刪除元素,雖然需要先通過遍歷找到位置(O(n)),但一旦找到,實際的插入/刪除操作本身是 O(1)?的,因為它只需要修改相鄰節點的指針,而不需要像?ArrayList?那樣移動大量元素。

3.?內存的“按需分配”

  • 與?ArrayList?預先分配數組不同,LinkedList?的每個節點都是在需要時才創建,內存使用更“靈活”,但每個節點有額外的?prev?和?next?引用開銷。

最終效果:


五、總結:LinkedList?的設計哲學

通過這次源碼級的剖析,我們可以總結出 LinkedList 的核心工作原理:

階段關鍵動作指針變化
創建初始化?first?和?last?指針first = null,?last = null
首次添加創建節點,first?和?last?都指向它first -> Node1,?last -> Node1
后續添加創建新節點,修改相鄰節點指針,更新?lastNode1.next -> Node2,?Node2.prev -> Node1,?last -> Node2

LinkedList 的“動態”源于其節點化指針鏈接的設計。它用 firstlast 兩個指針高效地管理鏈表的兩端,用 prevnext 構建了雙向的連接,使得頭尾操作異常迅速。

何時選擇 LinkedList

  • 頻繁在列表的頭部或尾部進行插入/刪除操作。
  • 需要實現棧(Stack)?或?隊列(Queue)?的數據結構(LinkedList?實現了?Deque?接口)。

何時避免 LinkedList

  • 需要頻繁進行隨機訪問get(index)),因為需要從頭或尾遍歷。
  • 內存非常緊張,因為每個節點有額外的引用開銷。

理解了 LinkedList 的雙向鏈表本質,你就能在 ArrayListLinkedList 之間做出更明智的選擇。

希望這篇解析能幫你徹底掌握 LinkedList 的源碼精髓!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/919629.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/919629.shtml
英文地址,請注明出處:http://en.pswp.cn/news/919629.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《P2700 逐個擊破》

題目背景三大戰役的平津戰場上&#xff0c;傅作義集團在以北平、天津為中心&#xff0c;東起唐山西至張家口的鐵路線上擺起了一字長蛇陣&#xff0c;并企圖在潰敗時從海上南逃或向西逃竄。為了就地殲敵不讓其逃走&#xff0c;指揮官制定了先切斷敵人東西兩頭退路然后再逐個殲滅…

C6.0:晶體管放大器的原理與應用(基極偏置篇)

將晶體管Q點偏置在負載線中點附近后&#xff0c;如果將一個小的交流信號耦合到基極上&#xff0c;便會產生一個交流的集電極電壓&#xff0c;交流集電極電壓與交流基極電壓波形相似&#xff0c;但是幅度要大了很多&#xff0c;即交流集電極電壓是對交流基極電壓的放大。本篇學習…

Oracle: cannot decrease column length because some value is too big

1.背景今天項目上查不到數據,查庫發現默認20位的字段被改為了200,用的還是char類型&#xff0c;填充了一堆空格 2.知識LENGTH() 函數用于計算字符串字段 長度TRIM() 函數用于去除字符串字段 column 前后的空格&#xff08;默認&#xff09;或指定字符&#xff1a;SUBSTR() 用于…

Elasticsearch 寫入全鏈路:從單機到集群

0. 先把術語擺正 Index&#xff08;索引&#xff09;&#xff1a;邏輯數據集合&#xff0c;≈ MySQL 的庫。Document&#xff08;文檔&#xff09;&#xff1a;一條 JSON 數據&#xff0c;≈ MySQL 的行。Field&#xff08;字段&#xff09;&#xff1a;文檔里的鍵值&#xff0…

Java多線程編程——基礎篇

目錄 前言 一、進程與線程 1、進程 2、線程 二、并發與并行 1、并發 2、并行 三、線程調度 1、CPU時間片 2、調度方式 ①時間片輪轉 ②搶占式調度 四、線程實現方式 1、繼承 Thread 類 Thread的多種構造函數&#xff1a; 2、實現 Runnable 接口 五、線程的核心方法 1、start() …

阿里云的centos8 服務器安裝MySQL 8.0

在 CentOS 8 上安裝 MySQL 8.0 可以通過添加 MySQL 官方 YUM 倉庫并使用 dnf 命令安裝。以下是具體步驟&#xff1a; 步驟如下&#xff1a; 下載并添加 MySQL 官方 YUM 倉庫 運行以下命令下載 MySQL 8.0 的 YUM 倉庫配置文件&#xff1a; sudo dnf install https://dev.mysql.…

【運維進階】Linux 正則表達式

Linux 正則表達式定義&#xff1a;正則表達式是一種pattern&#xff08;模式&#xff09;&#xff0c;用于與待搜索字符串匹配&#xff0c;以查找一個或多個目標字符串。組成&#xff1a;自成體系&#xff0c;由兩類字符構成普通字符&#xff1a;未被顯式指定為元字符的所有可打…

STM32輸入捕獲相位差測量技術詳解(基于TIM1復位模式)

本文將深入解析基于STM32定時器輸入捕獲功能的方波相位差測量技術&#xff0c;通過復位模式實現高精度相位檢測。以下是完整的代碼實現與詳細原理分析。一、相位差測量原理相位差測量基于兩個同頻方波信號下降沿時間差計算。核心原理&#xff1a;?復位模式?&#xff1a;將TIM…

什么是股指期貨可轉移阿爾法策略?

阿爾法&#xff08;Alpha&#xff09;是投資領域的一個術語&#xff0c;用來衡量投資組合的超額收益。簡單來說&#xff0c;阿爾法就是你在市場上賺的比平均水平多出來的那部分錢。比如&#xff0c;市場平均收益率是5%&#xff0c;但你的投資組合收益率是10%&#xff0c;那你的…

AXI GPIO S——ZYNQ學習筆記10

AXI GPIO 同意通道混合輸入輸出中斷控制#KEY set_property IOSTANDARD LVCMOS18 [get_ports {AXI_GPIO_KEY_tri_io[0]}] set_property PACKAGE_PIN J13 [get_ports {AXI_GPIO_KEY_tri_io[0]}] set_property IOSTANDARD LVCMOS18 [get_ports {AXI_GPIO_KEY_tri_io[1]}] set_pro…

如何通過傳感器選型優化,為設備壽命 “續航”?

在當今競爭激烈的工業領域&#xff0c;企業就像在一場沒有硝煙的戰爭中角逐&#xff0c;設備便是企業的“秘密武器”。設備的使用壽命&#xff0c;如同武器的耐用程度&#xff0c;直接決定了企業在生產戰場上的“戰斗力”。延長設備壽命&#xff0c;已然成為眾多企業降低生產成…

WebSocket連接的例子

// 初始化WebSocket連接 const initWebSocket () > {console.log("初始化鏈接中...")const websocketUrl ws://61.54.84.16:9090/;// WebSocket服務器地址websocket new WebSocket(websocketUrl)//使用真實的webscket// websocket new MockWebSocket(websocket…

c++之指針和引用

一 使用場景 C++ 什么時候使用指針?什么時候使用引用?什么時候應該按值傳遞?_引用什么時候用比較好-CSDN博客 只使用傳遞過來的值,而不對值進行修改 需要修改傳遞過來的值 內置數據類型 按值傳遞(小型結構) 指針傳遞 數組 指針傳遞 指針傳遞 結構 指針或引用(較大的結構…

pytorch學習筆記-模型訓練、利用GPU加速訓練(兩種方法)、使用模型完成任務

應該算是完結啦~再次感謝土堆老師&#xff01; 模型訓練 模型訓練基本可以分為以下幾個步驟按序執行&#xff1a; 引入數據集-使用dataloader加載數據集-建立模型-設置損失函數-設置優化器-進行訓練-訓練中計算損失&#xff0c;并使用優化器更新參數-模型測試-模型存儲 習慣上會…

深度卷積神經網絡AlexNet

在提出LeNet后卷積神經網絡在計算機視覺和機器學習領域中報有名氣&#xff0c;但是卷積神經網絡并沒有主導這些領域&#xff0c;因為LeNet在小數據集上取得了很好的效果&#xff0c;在更大&#xff0c;更真實的數據集上訓練卷積神經網絡的性能 和可行性有待研究&#xff0c;20世…

數據結構-HashSet

在 Java 編程的世界里&#xff0c;集合框架是極為重要的一部分&#xff0c;而 HashSet 作為 Set 接口的典型實現類&#xff0c;在處理不允許重復元素的場景中頻繁亮相。今天&#xff0c;我們就一同深入探究 HashSet&#xff0c;梳理它的特點、常用方法&#xff0c;以及和其他相…

心意行藥號 · 慈心方的八種用法

心意行藥號 慈心方的八種用法慈心方是心意行藥號589個珍貴秘方中的一個養生茶方&#xff0c;配伍比例科學嚴謹&#xff0c;君臣佐使堪稱經典&#xff0c;自古就有“小小慈心方&#xff0c;轉動大乾坤”之說。自清代光緒年間傳承至今&#xff0c;慈心方受益者逾百萬計&#xff…

Spring面試寶典:Spring IOC的執行流程解析

在準備Spring框架的面試時&#xff0c;“Spring IOC的工作流程是什么&#xff1f;” 是一個非常經典的問題。雖然網上有很多詳細的教程&#xff0c;但它們往往過于復雜&#xff0c;對于沒有深入研究過源碼的人來說理解起來確實有些困難。今天我們就來簡化這個概念&#xff0c;從…

學習日志39 python

1 fromkeys()函數是什么在 Python 中&#xff0c;fromkeys() 是字典&#xff08;dict&#xff09;的一個類方法&#xff0c;用于創建一個新字典。它的作用是&#xff1a;根據指定的可迭代對象&#xff08;如列表、元組等&#xff09;中的元素作為鍵&#xff08;key&#xff09;…

SpringBoot + MyBatis-Plus 使用 listObjs 報 ClassCastException 的原因與解決辦法

在項目中我們經常會遇到這種需求&#xff1a; 根據一組 ID 查詢數據庫&#xff0c;并返回指定字段列表。 我在寫代碼的時候&#xff0c;遇到了一個典型的坑&#xff0c;分享出來給大家。一、問題背景我的代碼是這樣寫的&#xff08;查詢項目表的負責人信息&#xff09;&#xf…