LinkedList源碼解析

1. 數據結構設計

(1) 節點結構

LinkedList 的核心是雙向鏈表節點 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;}
}
  • 雙向鏈接:每個節點同時記錄前驅和后繼,支持雙向遍歷。
  • 首尾指針:通過 firstlast 字段快速訪問鏈表兩端。

(2) 與 ArrayList 的存儲對比

特性LinkedListArrayList
底層結構雙向鏈表動態數組
內存占用更高(每個元素額外存儲指針)更低(連續內存)
CPU緩存友好性差(節點分散)好(局部性原理)

2. 核心操作實現

(1) 添加元素

尾部插入(add(E e)
public boolean add(E e) {linkLast(e); // 時間復雜度 O(1)return true;
}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++;
}
  • 優勢:無需擴容,直接修改指針。
指定位置插入(add(int index, E element)
public void add(int index, E element) {checkPositionIndex(index);if (index == size) {linkLast(element); // 尾部插入優化} else {linkBefore(element, node(index)); // 需要遍歷找到目標節點}
}Node<E> node(int 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;}
}
  • 時間復雜度
    • 頭尾操作:O(1)
    • 中間操作:O(n)(需遍歷)

(2) 刪除元素

remove(int index)
public E remove(int index) {checkElementIndex(index);return unlink(node(index)); // 先找到節點,再解除鏈接
}E unlink(Node<E> x) {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; // 幫助GCsize--;return element;
}
  • 關鍵點:正確處理頭尾節點的邊界條件。

(3) 訪問元素

get(int index)
public E get(int index) {checkElementIndex(index);return node(index).item; // 需遍歷鏈表
}
  • 性能缺陷:隨機訪問效率遠低于 ArrayList(O(n) vs O(1))。

3. 迭代器實現

(1) 普通迭代器 (Iterator)

private class ListItr implements ListIterator<E> {private Node<E> lastReturned;private Node<E> next;private int nextIndex;private int expectedModCount = modCount;public boolean hasNext() { return nextIndex < size; }public E next() {checkForComodification();if (!hasNext()) throw new NoSuchElementException();lastReturned = next;next = next.next;nextIndex++;return lastReturned.item;}
}
  • 快速失敗機制:通過 modCount 檢測并發修改。

(2) 雙向迭代器 (ListIterator)

支持向前遍歷:

public E previous() {checkForComodification();if (!hasPrevious()) throw new NoSuchElementException();lastReturned = next = (next == null) ? last : next.prev;nextIndex--;return lastReturned.item;
}

4. 線程安全與性能優化

(1) 線程安全問題

  • 非線程安全:并發修改會導致數據不一致或迭代器失效。
  • 解決方案
    List<String> syncList = Collections.synchronizedList(new LinkedList<>());
    
    或使用并發容器 ConcurrentLinkedDeque

(2) 設計取舍

操作LinkedListArrayList
頭部插入O(1)O(n)(需移動元素)
中間插入O(n)(查找)+ O(1)O(n)(移動元素)
隨機訪問O(n)O(1)
內存占用

5. 應用場景建議

  • 使用 LinkedList 的場景
    • 頻繁在 頭部/中部 插入刪除(如實現隊列/棧)。
    • 不需要頻繁隨機訪問。
  • 使用 ArrayList 的場景
    • 需要快速隨機訪問。
    • 內存敏感型應用。

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

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

相關文章

語雀批量導出知識庫

使用工具&#xff1a;yuque-dl 參考文檔&#xff1a; GitHub - gxr404/yuque-dl: yuque 語雀知識庫下載 Yuque-DL&#xff1a;一款強大的語雀資源下載工具_語雀文檔怎么下載-CSDN博客

電子電氣架構 --- 當前企業EEA現狀(下)

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 做到欲望極簡,了解自己的真實欲望,不受外在潮流的影響,不盲從,不跟風。把自己的精力全部用在自己。一是去掉多余,凡事找規律,基礎是誠信;二是…

flink中的窗口的介紹

本文重點 無界流會源源不斷的產生數據,有的時候我們需要把無界流進行切分成一段一段的有界數據,把一段內的所有數據看成一個整體進行聚合計算,這是實現無界流轉成有界流的方式之一。 為什么需要窗口 數據是源源不斷產生的,我們可能只關心某個周期內的統計結果。比如電費…

自建es 通過Flink同步mysql數據 Docker Compose

資源es:7.18 kibana:7.18 flink:1.17.2目錄mkdir -p /usr/project/flink/{conf,job,logs} chmod -R 777 /usr/project/flink #資源情況 mysql8.0 Elasticsearch7.18 自建# 目錄結構 /usr/project/flink/ /usr/project/flink/ ├── conf/ │ ├── flink-conf.yaml │ └…

AI瀏覽器和釘釘ONE是不是偽需求?

最近兩則新聞格外引起了我的注意&#xff1a;一是Claude推出了官方瀏覽器插件&#xff0c;二是釘釘發布了釘釘ONE。前者說明AI瀏覽器未必有必要&#xff0c;后者則描繪了一幅“刷刷手機就能完成工作”的未來辦公圖景。這幾天我經常在思考&#xff0c;AI瀏覽器是不是沒有必要&am…

從結構化到多模態:RAG文檔解析工具選型全指南

在RAG系統建設中&#xff0c;文檔解析質量直接決定最終效果上限&#xff0c;選擇合適的解析工具已成為避免"垃圾進&#xff0c;垃圾出"&#xff08;GIGO&#xff09;困境的關鍵決策。一、文檔解析&#xff1a;RAG系統的基石與瓶頸 當前企業知識庫中超過80%的信息存儲…

設計模式:享元模式(Flyweight Pattern)

文章目錄一、享元模式的介紹二、實例分析三、示例代碼一、享元模式的介紹 享元模式&#xff08;Flyweight Pattern&#xff09; 是一種結構型設計模式。通過共享相同對象&#xff0c;減少內存消耗&#xff0c;提高性能。 它摒棄了在每個對象中保存所有數據的方式&#xff0c; 通…

【Go語言入門教程】 Go語言的起源與技術特點:從誕生到現代編程利器(一)

文章目錄前言1. Go語言的起源與發展2. Go語言的核心設計團隊2.1 Ken Thompson&#xff08;肯湯普森&#xff09;2.2 Rob Pike&#xff08;羅布派克&#xff09;2.3 Robert Griesemer&#xff08;羅伯特格瑞澤默&#xff09;設計動機&#xff1a;解決C的痛點3. Go語言的核心特性…

rocketmq啟動與測試

1.更改runserver.sh的內存大小 vi runserver.sh 2.更改 runbroker.sh內存大小 vi runbroker.sh3.設置環境變量 vi ~/.bash_profile 新增 export NAMESRV_ADDRlocalhost:98764.啟動 --在bin的上一級目錄啟動 nohup bin/mqnamesrv & nohup bin/mqbroker &5.查看日志 le…

11.《簡單的路由重分布基礎知識探秘》

11_路由重分布 文章目錄11_路由重分布路由重分布概述路由重分布的核心作用基礎實驗實驗流程實驗拓撲配置示例(基本操作省略)實驗結論路由重分布概述 路由重分布&#xff08;又稱路由引入&#xff09;是指在不同路由協議之間交換路由信息的技術。在復雜網絡中&#xff0c;可能同…

C++ 左值引用與右值引用介紹

C 左值引用與右值引用詳解 在 C 的類型系統中&#xff0c;引用&#xff08;reference&#xff09; 是一種為已有對象起別名的機制。在早期&#xff08;C98/03&#xff09;中&#xff0c;C 只有 左值引用&#xff08;lvalue reference&#xff09;&#xff0c;主要用于函數參數…

基于物聯網設計的園林灌溉系統(華為云IOT)_274

文章目錄 一、前言 1.1 項目介紹 【1】項目開發背景 【2】設計實現的功能 【3】項目硬件模塊組成 【4】設計意義 【5】國內外研究現狀 【6】摘要 1.2 設計思路 1.3 系統功能總結 1.4 開發工具的選擇 【1】設備端開發 【2】上位機開發 1.5 參考文獻 1.6 系統框架圖 1.7 系統原理…

uni-app iOS 應用版本迭代與上架實踐 持續更新的高效流程

很多團隊在使用 uni-app 開發 iOS 應用時&#xff0c;往往能順利完成第一次上架&#xff0c;但一到 版本更新和迭代 環節&#xff0c;就會頻繁遇到瓶頸&#xff1a;證書是否能復用&#xff1f;如何快速上傳&#xff1f;怎樣保持節奏不被打亂&#xff1f; 本文結合實戰經驗&…

解決由Tomcat部署前端改成nginx部署,導致大寫.JPG結尾文件無法訪問問題

前言&#xff1a;因信創替代要求&#xff0c;在麒麟服務器部署新的應用。原先的架構&#xff1a;前端tomcat部署&#xff0c;源碼部署java應用&#xff08;ps&#xff1a;前后端&#xff0c;文件都在同一臺服務器上&#xff09;&#xff0c;前端訪問后端&#xff0c;再通過后端…

【設計模式】三大原則 單一職責原則、開放-封閉原則、依賴倒轉原則

系列文章目錄 文章目錄系列文章目錄一、單一職責原則方塊游戲的設計二、開放-封閉原則原則介紹何時應對變化三、依賴倒轉原則依賴倒轉原則介紹里氏代換原則總結一、單一職責原則 單一職責原則&#xff0c;聽字面意思&#xff0c;就是說功能要單一&#xff0c;他的準確解釋是&a…

(3dnr)多幀視頻圖像去噪 (一)

一、多幀視頻圖像去噪 原理當攝像機每秒捕捉的圖像達到60FPS&#xff0c;除了場景切換或者一些快速運動的場 景外&#xff0c;視頻信號中相鄰的兩幀圖像內容大部分是相同的。并且視頻信號中的噪 聲大部分都是均值為零的隨機噪聲&#xff0c;因此在時間上對視頻信號做幀平均&…

從靜態到智能:用函數式接口替代傳統工具類

在 Java 早期開發中&#xff0c;我們習慣使用**靜態實用程序類&#xff08;Utility Class&#xff09;**來集中放置一些通用方法&#xff0c;例如驗證、字符串處理、數學計算等。這種模式雖然簡單直接&#xff0c;但在現代 Java 開發&#xff08;尤其是 Java 8 引入 Lambda 和函…

免殺偽裝 ----> R3進程偽裝實戰(高階) ---->培養紅隊免殺思路

目錄 R3進程偽裝(免殺技術)高階技術說明 深入剖析Windows進程規避免殺技術 學習R3進程偽裝的必備技能 R3進程偽裝的核心知識點與實現步驟 核心知識點 實現步驟 免殺實現步驟 PEB與EPROCESS的深入解析 1. PEB&#xff08;進程環境塊&#xff09; 2. EPROCESS 3. PEB與…

深度學習——基于卷積神經網絡實現食物圖像分類(數據增強)

文章目錄 引言 一、項目概述 二、環境準備 三、數據預處理 3.1 數據增強與標準化 3.2 數據集準備 四、自定義數據集類 五、構建CNN模型 六、訓練與評估 6.1 訓練函數 6.2 評估函數 6.3 訓練流程 七、關鍵技術與優化 八、常見問題與解決 九、完整代碼 十、總結 引言 本文將詳細介…

【開題答辯全過程】以 基于微信小程序的教學輔助系統 為例,包含答辯的問題和答案

個人簡介一名14年經驗的資深畢設內行人&#xff0c;語言擅長Java、php、微信小程序、Python、Golang、安卓Android等開發項目包括大數據、深度學習、網站、小程序、安卓、算法。平常會做一些項目定制化開發、代碼講解、答辯教學、文檔編寫、也懂一些降重方面的技巧。感謝大家的…