ArrayList源碼分析、擴容機制面試題,數組和List的相互轉換,ArrayList與LinkedList的區別

目錄

1.java集合框架體系

2. 前置知識-數組

2.1?數組

2.1.1 定義:

2.1.2 數組如何獲取其他元素的地址值?(尋址公式)

2.1.3?為什么數組索引從0開始呢?從1開始不行嗎?

3. ArrayList

3.1 ArrayList和和Vector的區別?(了解)

3.2?ArrayList 可以添加 null 值嗎?

3.3?ArrayList源碼

成員變量

?編輯構造方法

3.4 ArrayList 底層實現原理 ★

3.5?ArrayList list = new ArrayList(10)中的list擴容幾次?★

3.6?數組和List之間相互轉換?★

3.7?數組和List之間相互轉換過程中,數據發生修改,結果會變嗎(有影響嗎)?★

3.7.1? 用Arrays.asList() 轉List后,如修改了數組內容,list集合結果受影響嗎?

3.7.2 List用toArray() 轉數組后,如果修改了List內容,數組受影響嗎?

4. 前置知識-鏈表

4.1單向鏈表

4.1.1 單向鏈表特點及參考源碼

4.1.2?單向鏈表時間復雜度分析

1 查詢操作

2 插入和刪除操作

4.2 雙向鏈表

4.2.1?雙向鏈表特點及參考源碼

4.2.2?雙向鏈表時間復雜度分析

1.?查詢操作

2 增刪操作

5.?LinkedList

6.?ArrayList與LinkedList區別?★


1.java集合框架體系

2. 前置知識-數組

2.1?數組

2.1.1 定義:

數組(Array)是一種用連續內存空間存儲相同數據類型數據的線性數據結構。

int[] array = {22,33,88,66,55,25};

2.1.2 數組如何獲取其他元素的地址值?(尋址公式

在數組在內存中查找元素的時候,是有一個尋址公式的,如下:
arr[i] = baseAddress + i * dataTypeSize

2.1.3?為什么數組索引從0開始呢?從1開始不行嗎?

實際上并不是不行。而是如果數組索引從1開始的話,整體性能會變低。
因為尋址公式會變為a[i] = baseAddress + (i-1) *dataTypeSize,也就是說,多了一個減法操作。

3. ArrayList

ArrayList 的底層是數組隊列,相當于動態數組。與 Java 中的數組相比,它的容量能動態增長。在添加大量元素前,應用程序可以使用ArrayList底層API的 ensureCapacity()操作來增加 ArrayList 實例的容量。這可以減少遞增式再分配的數量。

?

3.1 ArrayList和和Vector的區別?(了解)

  • ArrayList 是 List 的主要實現類,底層使用 Object[]存儲,適用于頻繁的查找工作,線程不安全 。 ?

  • Vector 是 List 的古老實現類,底層使用Object[] 存儲,線程安全。

3.2?ArrayList 可以添加 null 值嗎?

可以。ArrayList 中可以存儲任何類型的對象,包括 null 值。不過,不建議向ArrayList 中添加 null 值, null 值無意義,會讓代碼難以維護比如忘記做判空處理就會導致空指針異常。

3.3?ArrayList源碼

成員變量

構造方法

第一個構造是帶初始化容量的構造函數,可以按照指定的容量初始化數組
第二個是無參構造函數,默認創建一個空集合
/***構造包含指定collection元素的列表,這些元素利用該集合的迭代器按順序返回*如果指定的集合為null,throws NullPointerException。*/
public ArrayList(Collection<? extends E> c) {elementData = c.toArray();if ((size = elementData.length) != 0) {if (elementData.getClass() != Object[].class)elementData = Arrays.copyOf(elementData, size, Object[].class);} else {// replace with empty array.this.elementData = EMPTY_ELEMENTDATA;}
}
collection 對象轉換成數組,然后將數組的地址的賦給 elementData

3.4 ArrayList 底層實現原理 ★

1. 底層數據結構

ArrayList 底層是用動態的數組實現的

2. 初始容量

ArrayList 初始容量為 0 ,當第一次添加數據的時候才會初始化容量為 10

3. 擴容邏輯

ArrayList 在進行擴容的時候是原來容量的 1.5 倍,每次擴容都需要拷貝數組

4. 添加邏輯

添加數據的流程:

1. 確保數組已使用長度( size )加 1 之后足夠存下下一個數據
2. 計算數組的容量,如果當前數組已使用長度 +1 后的大于當前的數組長度,
3. 則調用 grow 方法擴容(原來的 1.5 倍)
4. 確保新增的數據有地方存儲之后,則將新元素添加到位于 size 的位置上。
5. 返回添加成功布爾值。

3.5?ArrayList list = new ArrayList(10)中的list擴容幾次?

答:該語句只是聲明和實例了一個 ArrayList ,指定了容量為 10 ,未擴容

ArrayList的擴容機制如下:

  1. ArrayList被初始化時,如果沒有指定初始容量,它將使用默認的初始容量(10)。

  2. 當添加元素超過當前容量時,ArrayList會進行擴容。默認情況下,擴容后的容量是當前容量的1.5倍(即增加50%)。

3.6?數組和List之間相互轉換?★

參考回答:

  • 數組轉List ,使用JDKjava.util.Arrays工具類的asList方法,返回一個List集合
  • List轉數組,使用ListtoArray方法。無參toArray方法返回 Object數組,傳入初始化長度的數組對象,返回該對象數組

3.7?數組和List之間相互轉換過程中,數據發生修改,結果會變嗎(有影響嗎)?★

分為兩種情況:

3.7.1? 用Arrays.asList() 轉List后,如修改了數組內容,list集合結果受影響嗎?

答:會受影響

Arrays.asList 方法返回的是一個固定大小的列表,它的底層仍然是原始數組。

當你通過 Arrays.asList 獲得的列表并嘗試修改其中的元素時,實際上是在修改原始數組的內容,因為列表中的元素和數組中的元素是同一個對象(同一個地址引用)。

源碼如下:

3.7.2 List用toArray() 轉數組后,如果修改了List內容,數組受影響嗎?

答:不會影響。

list用了toArray轉數組后,如果修改了list內容,數組不會影響,當調用了toArray ?以后,在底層是它是進行了數組的拷貝,跟原來的元素就沒啥關系了,所以即使 ?list修改了以后,數組

也不受影響

4. 前置知識-鏈表

LinkedList 底層數據結構——雙向鏈表

4.1單向鏈表

4.1.1 單向鏈表特點及參考源碼

  • 鏈表中的每一個元素稱之為結點(Node
  • 物理存儲單元上,非連續、非順序的存儲結構
  • 單向鏈表:每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個 是存儲下一個結點地址的指針域。記錄下個結點地址的指針叫作后繼指針next

代碼實現參考:

4.1.2?單向鏈表時間復雜度分析

1 查詢操作

查詢:頭節點:O(1),一般情況:O(n)
  • 只有在查詢頭節點的時候不需要遍歷鏈表,時間復雜度是O(1)
  • 查詢其他結點需要遍歷鏈表,時間復雜度是O(n)
2 插入和刪除操作

增刪:頭節點:O(1),一般情況:O(n)

  • 只有在添加和刪除頭節點的時候不需要遍歷鏈表,時間復雜度是O(1)
  • 添加或刪除其他結點需要遍歷鏈表找到對應節點后,才能完成新增或刪除節點,時間復雜度是O(n)

4.2 雙向鏈表

4.2.1?雙向鏈表特點及參考源碼

而雙向鏈表,顧名思義,它支持兩個方向
  • 每個結點不止有一個后繼指針 next 指向后面的結點
  • 有一個前驅指針 prev 指向前面的結點
代碼實現參考:

4.2.2?雙向鏈表時間復雜度分析

1.?查詢操作

查詢:頭尾節點:O(1),一般情況:O(n),給定節點找前驅節點:O(1)

  • 查詢頭尾結點的時間復雜度是O(1)
  • 平均的查詢時間復雜度是O(n)
  • 給定節點找前驅節點的時間復雜度為O(1)
2 增刪操作
增刪:頭尾節點:O(1),一般情況:O(n),給定節點找前驅節點:O(1)
  • 頭尾結點增刪的時間復雜度為O(1)
  • 其他部分結點增刪的時間復雜度是 O(n)
  • 給定節點增刪的時間復雜度為O(1)

5.?LinkedList

LinkedList 底層數據結構——雙向鏈表

查詢快,增刪改慢,適用于讀多寫少的場景

6.?ArrayList與LinkedList區別?★

從四個方面來談。

  • 底層數據結構:ArrayList 是動態數組的數據結構實現,LinkedList 是雙向鏈表的數據結構實現
  • 效率上,除了 LinkedList不支持下標查詢,ArrayList支持下標查詢。其他都差不多。
  • 空間上,ArrayList底層是數組,內存連續,節省內存。LinkedList 是雙向鏈表需要存儲數據,和兩個指針,更占用內存。
  • 線程安全問題,ArrayList和LinkedList都不是線程安全的。

如果需要保證線程安全,有兩種方案:

  • 在方法內使用,局部變量則是線程安全的
  • 使用線程安全的ArrayList和LinkedList:
Collections.synchronizedList(new ArrayList<>());
Collections.synchronizedList(new LinkedList<>());

還有一下三個方面的區別可以了解一下:

  • 插入和刪除是否受元素位置的影響:
    • ArrayList?采用數組存儲,所以插入和刪除元素的時間復雜度受元素位置的影響。 比如:執行add(E e)方法的時候,?ArrayList?會默認在將指定的元素追加到此列表的末尾,這種情況時間復雜度就是 O(1)。但是如果要在指定位置 i 插入和刪除元素的話(add(int index, E element)),時間復雜度就為 O(n)。因為在進行上述操作的時候集合中第 i 和第 i 個元素之后的(n-i)個元素都要執行向后位/向前移一位的操作。
    • LinkedList?采用鏈表存儲,所以在頭尾插入或者刪除元素不受元素位置的影響(add(E e)addFirst(E e)addLast(E e)removeFirst()、?removeLast()),時間復雜度為 O(1),如果是要在指定位置?i?插入和刪除元素的話(add(int index, E element)remove(Object o),remove(int index)), 時間復雜度為 O(n) ,因為需要先移動到指定位置再插入和刪除。
  • 是否支持快速隨機訪問:?LinkedList?不支持高效的隨機元素訪問,而?ArrayList(實現了?RandomAccess?接口) 支持。快速隨機訪問就是通過元素的序號快速獲取元素對象(對應于get(int index)方法)。
  • 內存空間占用:?ArrayList?的空間浪費主要體現在在 list 列表的結尾會預留一定的容量空間,而 LinkedList 的空間花費則體現在它的每一個元素都需要消耗比 ArrayList 更多的空間(因為要存放直接后繼和直接前驅以及數據)。

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

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

相關文章

【C++】- 掌握STL List類:帶你探索雙向鏈表的魅力

文章目錄 前言&#xff1a;一.list的介紹及使用1. list的介紹2. list的使用2.1 list的構造2.2 list iterator的使用2.3 list capacity2.4 list element access2.5 list modi?ers2.6 list的迭代器失效 二.list的模擬實現1. list的節點2. list的成員變量3.list迭代器相關問題3.1…

Docker--Docker Container(容器) 之容器實戰

對docker容器的前兩篇文章 Docker–Docker Container(容器) 之 操作實例 Docker–Docker Container(容器&#xff09; Mysql容器化安裝 我們可以先在Docker Hub上查看對應的Mysql鏡像,拉取對應的鏡像&#xff1a; 拉取mysql5.7版本的鏡像&#xff1a; docker pull mysql:5.7…

ModuleNotFoundError: No module named ‘torchvision.transforms.functional_tensor‘

問題&#xff1a; 運行代碼時&#xff0c;報錯&#xff1a; … File “/home/xzy/anaconda3/envs/groundinggpt/lib/python3.10/site-packages/pytorchvideo/transforms/augmix.py”, line 6, in from pytorchvideo.transforms.augmentations import ( File “/home/xzy/anac…

【匯編語言】內中斷(二) —— 安裝自己的中斷處理程序:你也能控制0號中斷

文章目錄 前言1. 編程處理0號中斷1.1 效果演示1.2 分析所要編寫的中斷處理程序1.2.1 引發中斷1.2.2 中斷處理程序1.2.3 中斷處理程序do0應該存放的位置1.2.4 中斷向量表的修改1.2.5 總結 1.3 程序框架1.4 注意事項1.5 從CPU的角度看中斷處理程序1.6 一些問題的思考與解答 2. 安…

華為OD E卷(100分)23-連續字母長度

前言 工作了十幾年&#xff0c;從普通的研發工程師一路成長為研發經理、研發總監。臨近40歲&#xff0c;本想辭職后換一個相對穩定的工作環境一直干到老, 沒想到離職后三個多月了還沒找到工作&#xff0c;愁腸百結。為了讓自己有點事情做&#xff0c;也算提高一下自己的編程能力…

VS2019中無法跳轉定義_其中之一情況

我習慣了使用VS2019看stm的代碼&#xff1b; 遇到的問題&#xff0c;在導入代碼后&#xff0c;發現有些函數調用不能跳轉到定義&#xff1b; 問題描述步驟 1、導入代碼 2、跳轉&#xff0c;無法跳轉 1、中文路徑 2、刪除.vs文件 和網上查的都沒辦法解決 最后發現是VS不支持 …

讓 Win10 上網本 Debug 模式 QUDPSocket 信號槽 收發不丟包的方法總結

在前兩篇文章里&#xff0c;我們探討了不少UDP丟包的解決方案。經過幾年的摸索測試&#xff0c;其實方法非常簡單, 無需修改代碼。 1. Windows 下設置UDP緩存 這個方法可以一勞永逸解決UDP的收發丟包問題&#xff0c;只要添加注冊表項目并重啟即可。即使用Qt的信號與槽&#…

【設計模式】觀察者模式深度講解

文章目錄 概覽一、定義與特點二、角色與職責三、實現方式四、應用場景五、優缺點 Java實現Python實現 概覽 觀察者模式&#xff08;Observer Pattern&#xff09;是一種行為型設計模式&#xff0c;它定義了一種一對多的依賴關系&#xff0c;讓多個觀察者對象同時監聽某一個主題…

Elasticsearch:ES|QL 中的全文搜索 - 8.17

細心的開發者如果已經閱讀我前兩天發布的文章 “Elastic 8.17&#xff1a;Elasticsearch logsdb 索引模式、Elastic Rerank 等”&#xff0c;你就會發現在 8.17 的發布版中&#xff0c;有一個重要的功能發布。那就是 ES|QL 開始支持全文搜索了。在今天的文章中我們來嘗試一下。…

SQL和Python 哪個更容易自學?

SQL和Python不是一個物種&#xff0c;Python肯定更難學習。如果你從事數據工作&#xff0c;我建議先學SQL、有余力再學Python。因為SQL不光容易學&#xff0c;而且前期的投入產出比更大。 SQL是數據查詢語言&#xff0c;場景限于數據查詢和數據庫的管理&#xff0c;對大部分數據…

【unity】從零開始制作平臺跳躍游戲--界面的認識,添加第一個角色!

在上一篇文章中&#xff0c;我們已經完成了unity的環境配置與安裝?? 【Unity】環境配置與安裝-CSDN博客 接下來&#xff0c;讓我們開始新建一個項目吧&#xff01; 新建項目 首先進入unityHub的項目頁面&#xff0c;點擊“新項目”&#xff1a; 我們這個系列將會以2D平臺…

怎么禁用 vscode 中點擊 go 包名時自動打開瀏覽器跳轉到 pkg.go.dev

本文引用怎么禁用 vscode 中點擊 go 包名時自動打開瀏覽器跳轉到 pkg.go.dev 在 vscode 設置項中配置 gopls 的 ui.navigation.importShortcut 為 Definition 即可。 "gopls": {"ui.navigation.importShortcut": "Definition" }ui.navigation.i…

Unity3D實現抽象類的應用場景例子

系列文章目錄 unity知識點 文章目錄 系列文章目錄??前言??一、示例??二、使用步驟??三、抽象類和接口的區別??3-1、抽象類??3-2、接口類??壁紙分享??總結??前言 假設我們正在制作一個游戲,游戲中有多種不同類型的角色,這些角色都有一些共同的行為(比如移…

數據倉庫工具箱—讀書筆記01(數據倉庫、商業智能及維度建模初步)

數據倉庫、商業智能及維度建模初步 記錄一下讀《數據倉庫工具箱》時的思考&#xff0c;摘錄一些書中關于維度建模比較重要的思想與大家分享&#x1f923;&#x1f923;&#x1f923; 博主在這里先把這本書"變薄"~有時間的小伙伴可以親自再讀一讀&#xff0c;感受一下…

docker啟動一個helloworld(公司內網服務器)

這里寫目錄標題 容易遇到的問題&#xff1a;1、docker連接問題 我來介紹幾種啟動 Docker Hello World 的方法&#xff1a; 最簡單的方式&#xff1a; docker run hello-world這會自動下載并運行官方的 hello-world 鏡像。 使用 Nginx 作為 Hello World&#xff1a; docker…

計算機組成原理(五):程序裝載

在計算機組成原理中&#xff0c;程序裝載&#xff08;Program Loading&#xff09;是指將程序從外存&#xff08;如磁盤&#xff09;加載到內存中&#xff0c;并為其運行做好準備的過程。程序裝載是實現程序從靜態存儲狀態到動態運行狀態的關鍵環節&#xff0c;涉及地址映射、內…

Python+OpenCV系列:模版匹配

文章目錄 1. 模板匹配基本原理2. cv2.matchTemplate() 函數函數原型&#xff1a; 3. 模板匹配步驟4. 單目標模板匹配示例5. 多目標模板匹配多目標模板匹配示例代碼解析&#xff1a; 6. 多模板匹配多模板匹配示例代碼解析 7. 總結 模板匹配是一種在圖像中尋找模板的位置的方法。…

基于IEEE 802.1Qci的時間敏感網絡(TSN)主干架構安全分析及異常檢測系統設計

中文標題&#xff1a;基于IEEE 802.1Qci的時間敏感網絡&#xff08;TSN&#xff09;主干架構安全分析及異常檢測系統設計 英文標題&#xff1a;Security Analysis of the TSN Backbone Architecture and Anomaly Detection System Design Based on IEEE 802.1Qci 作者信息&…

怎樣提升企業網絡的性能?

企業網絡的穩定性和高效性直接影響員工的工作效率。以下從多維度分析了一些有效策略&#xff0c;幫助公司提升網絡性能&#xff0c;營造更高效的辦公環境。 1. 升級網絡設備 采用性能更高的網絡硬件是優化網絡體驗的重要基礎。選擇支持高吞吐量、低延遲的設備&#xff08;如企業…

scala基礎_數據類型概覽

Scala 數據類型 下表列出了 Scala 支持的數據類型&#xff1a; 類型類別數據類型描述Scala標準庫中的實際類基本類型Byte8位有符號整數&#xff0c;數值范圍為 -128 到 127scala.Byte基本類型Short16位有符號整數&#xff0c;數值范圍為 -32768 到 32767scala.Short基本類型I…