關于List集合類ArrayList、LinkedList、Vector詳解

在這里插入圖片描述

??各位小伙伴們大家好,歡迎來到這個小扎扎的《Java核心技術 卷Ⅰ》筆記專欄,在這個系列專欄中我將記錄淺學這本書所得收獲,鑒于 看到就是學到、學到就是賺到 精神,這波簡直就是血賺

💡涉及的知識點速通

  • 🛫 關于List集合類你都知道什么?
    • 🪂 List接口三個實現類的異同?
    • 🪂 ArrayList類源碼淺析
    • 🪂 LinkedList類源碼淺析
    • 🪂 vector類源碼簡析
  • 🛫 List的常用API都有哪些?
    • 🪂 List接口的常用API
    • 🪂 linkedList類的特有API
    • 🪂 List集合類的API分析

🛫 關于List集合類你都知道什么?

??我們將實現了List接口的類稱為是List集合類,List集合類中元素存儲有一個特點:有序、可重復,List接口常用的有三個實現類:ArrayList、LinkedList和Vector

🪂 List接口三個實現類的異同?

??三者相同點:ArrayList、LinkedList和Vector都實現了List接口,所以它們存儲數據的特點都一致,那就是有序、可重復

??ArrayList和Vector相比,相同點就是底層結構上都用到了Object [ ]數組存儲元素,不同點就是ArrayList是線程不安全但是效率高的,而Vector是線程安全但是效率低的,造成這個不同的原因就是Vector中的方法都使用了同步鎖,這樣在保證線程安全的同時也會降低它的效率

??ArrayList和LinkedList相比最大的不同點就是底層存儲結構,上面說過ArrayList使用的是Object [ ]數組存儲元素,而LinkedList則是使用雙向鏈表進行存儲,雙向鏈表的特點就是將每一個元素都存儲在一個單獨的鏈接(link)中,這個鏈接由三部分組成:上一個鏈接的運用、數據、下一個鏈接的引用,雙向鏈表就是通過上下引用將所有的鏈接鏈成一張表。在這里插入圖片描述??要知道數組最令人詬病的就是對元素的添加和刪除,每次操作都需要移動它后面的所有元素,雙向鏈表每次添加和刪除元素只和它前后的兩link有關,只需要改變上下鏈接的引用即可,這樣的話就可以很好的解決這個弊端。于是,涉及到頻繁的添加刪除操作的話,可以選擇使用LinkedList集合。但是由于數組中可以使用索引快速定位一個元素,而鏈表則是需要從頭開始順著鏈查找,所以涉及到頻繁的查詢數據可以選擇使用ArrayList

🪂 ArrayList類源碼淺析

??ArrayList的源碼在jdk 7和jdk 8之間還是有些設計上的不同的,接下來就通過對兩個版本的分析來體會不同點,并思考一下jdk 8改變設計的原因

jdk 7在這里插入圖片描述??使用無參構造器創建一個ArrayList對象會調用它的有參構造器并傳參為10,也就是說使用無參構造器默認創建一個長度為10的Object [ ]數組。然后每次調用add方法添加元素之前都會通過ensureCapacityInternal方法判斷當前集合再添加新元素,也就是集合中元素個數size + 1之后會不會大于數組長度,如果超過的話就調用grow方法進行擴容。擴容的時候先將當前數組長度擴大1.5倍,如果擴大1.5之后還是無法沒有size + 1大的話直接將擴容后的數組長度設置為size + 1;如果擴大1.5倍之后大于給定的常量值,判斷size + 1有沒有大于這個常量值,大于的話數組長度設為整型的最大值,否則就設置成給定的常量值;至此擴容后的數組長度newCapacity就確定了,然后就是調用Arrays工具類的copyOf方法將原來的數組內容拷貝到長度為newCapacity的新數組中

??數組擴容完成之后就是添加新元素,回到add方法中,將參數元素添加到數組中索引為size的位置,然后size + 1索引向后移(這一步就是size++的效果),如果數組無需擴容的話就直接執行添加操作
jdk 8在這里插入圖片描述??jdk 8 的時候ArrayList集合調用無參構造器默認創建一個空數組對象,而不是一個有長度的數組,這樣做的好處就是可以節省內存提高效率。jdk 7 就是創建一個長度為10的數組,這樣的話一旦加載ArrayList類就會給數組定義長度就要按照長度分配內存空間;而jdk 8 中則使用空數組解決了這個問題,等到ArrayList集合調用add方法添加元素的時候才會動態的創建數組,類似于單例設計模式的懶漢模式思想

??調用add方法都會發生什么呢?根據上圖源碼淺析一下,為了便于區分不同的方法調用使用不同顏色標記。
在添加元素之前,先將當前集合再添加新元素時的長度,也就是集合中元素個數size + 1之后的值,使用②③方法進行一系列的判斷
判斷當前的數組是否為空,如果為空的話返回默認數組長度10與size + 1之間的最大值,否則直接返回size + 1
將②中的返回值作為參數執行③方法判斷size + 1的大小是否大于數組的長度,如果是的話就調用grow方法擴容
擴容的機制和jdk 7中的一致,先將當前數組長度擴大1.5倍,如果擴大1.5之后還是無法沒有size + 1大的話直接將擴容后的數組長度設置為size + 1;如果擴大1.5倍之后大于給定的常量值,判斷size + 1有沒有大于這個常量值,大于的話數組長度設為整型的最大值,否則就設置成給定的常量值;至此擴容后的數組長度newCapacity就確定了,然后就是調用Arrays工具類的copyOf方法將原來的數組內容拷貝到長度為newCapacity的新數組中

??根據上述分析,梳理jdk 8 的時候ArrayList集合第一次添加元素流程:首先實例化ArrayList對象的時候會調用無參構造器創建一個空數組對象,然后第一次調用add方法添加元素會被攔截到方法②③進行判斷,執行方法②的時候數組為空對象執行判斷體返回10(默認數組長度)和1(size + 1)的最大值10,然后執行方法③10(方法②返回值作③的參數)減去0(空數組長度)>0,執行判斷體中方法④擴容數組,空數組擴容1.5倍還是小于10,所以將新數組長度定為10,并將原空數組拷貝到新數組中(這一步雖然像廢話但是代碼中定義有),最后將add的參數放到索引為0的位置,然后索引自增1

所以說,有了上面分析的前車之鑒,大家如果在使用ArrayList集合的時候明顯知道元素的個數,或者知道一定多于10個的話,可以在創建ArrayList對象的時候使用有參構造器指定底層數組的長度,這樣的話就可以避免向集合對象中添加元素的時候多次擴容,提高程序的效率


🪂 LinkedList類源碼淺析

在這里插入圖片描述??LinkedList類內部定義了一個內部類Node也就是雙向鏈表的一個節點,前面講過它是由三個部分組成,于是內部類Node也包含三個屬性與之對應(上一個節點的引用 => prev、數據 => item、下一個節點的引用 => next),然后使用無參構造器創建LinkedList對象底層什么都不創建并不會像ArrayList一樣創建一個數組啥的,但是它會默認初始化類屬性first(頭結點)和last(尾結點)為null。

??再之后就是調用add方法添加元素了,add方法底層使用的是linkLast方法,第一次添加元素的時候last的值為默認初始化的null,否則就是原鏈表的尾節點。將last的值賦值給 l 這個 l 就是通過有參構造器創建Node對象時的第一個參數,也就是將新鏈接的前一個節點引用指向原鏈表的尾節點,然后第二個參數是數據e,第三個參數是null(因為將數據添加到了最后,后面沒有節點了,所以下一個節點的引用為null)。將創建好的Node對象賦值給last也就是指定新鏈表的尾節點,l 是null的話就將創建好的Node對象也賦值給first也就是指定新鏈表的頭節點,表示新鏈表的頭節點和尾節點都是新建節點(因為第一次添加元素雙向鏈表中就只有一個節點);如果不為null的話就將原鏈表的尾節點的下一個鏈接的引用指向新節點。

??根據上面的分析可以得知,所有的新節點都鏈在了雙向鏈表的尾部,所以這種方法就是雙向鏈表的尾插法

🪂 vector類源碼簡析

??由于vector類已經很久未更新,于是它的底層源碼就和ArrayList的jdk 7 版本的幾乎一致,使用無參構造器創建對象的時候會調用有參構造器創建一個長度為10的object數組,只不過是擴容的時候會擴容到原來長度的2倍,它和ArrayList的區別前面也說過就是vector的方法上都加了鎖,因此會犧牲性能來保證線程安全

🛫 List的常用API都有哪些?

🪂 List接口的常用API

在這里插入圖片描述

🪂 linkedList類的特有API

??由于linkedList底層特有的雙向鏈表結構,所以它提供了一些可以對鏈頭或者鏈尾元素進行操作的API在這里插入圖片描述

🪂 List集合類的API分析

??以下是List集合類的繼承實現關系,由于沒有系統的學過UML圖,所以用文字表示了繼承實現關系,大家將就將就看🤐
在這里插入圖片描述??三個集合類都間接實現了Collection接口,所以上一篇博客里涉及到的Collection接口API,在這三個集合類依舊可以使用,但是Collection接口中的API方法都是抽象方法,是不會就意味著我們需要自己在類中實現這些方法的方法體呢?并不是,還記得我們說完Collection接口之后有接觸到了一個類叫AbstractCollection,它實現了Collection接口中大部分常用的API的默認方法體,而我們的三個類都間接繼承了這個AbstractCollection類,所以說,類中無需實現Collection接口中的方法,而是直接使用即可

??除了Collection的API之外,List集合類還都間接實現了List接口,所以List接口中的API在這三個集合類也可以直接使用,由于列表多是數組作底層結構,所以List接口中的API也都大多有索引的參數用于直接定位到某個元素。毋庸置疑的是List接口中的API也會是抽象的,所以它也有一個和Collection接口一樣的實現類AbstractList提供了這些抽象方法的默認實現,三個集合類也都繼承了這個實現類,所以直接使用即可無需提供實現

??與此同時,List集合類還都間接實現了Iterator接口,所以都可以直接使用Iterator接口的API,借助迭代器遍歷集合中的每一個元素。Iterator接口中有一個很重要的方法forEach,可以直接操作集合中的所有元素,具體操作使用Lambda表達式寫在forEach方法參數里

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

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

相關文章

1562a檢測軟件_洛達1562a空間音頻版評測!!!

哈嘍大家好!這里是小澤,一個不專業的Beatboxer~~~今天給大家帶來一期HQB最新空間音頻版洛達1562a耳機的評測視頻,建議先贊再看!(滑稽)聽說你不點贊?昨晚拍了一晚,但是因為是第一次搞…

python 趣味編程課_青少年編程:Python趣味編程基礎入門課程

課程目錄 章節1:編程課前說明試看 課時1 編程課前說明07:49可試看 章節2:第一章 Python基礎-認識環境試看 課時2 1、什么是計算機程序和編程?08:48可試看 課時3 2、為什么學習編程?03:10可試看 課時4 3、Python的安裝11:48可試看 課時5 4、用Python編寫第…

shell181網格劃分_ANSYS中Shell181單元介紹誰知道

再畢業設計做模型中要應用到SHELL181單元,那么這個單元有什么好處誰能具體的告訴我下,我有英文但是有的地方翻譯不通。或者誰能幫我翻譯一下~謝謝~SHELL181issuitableforanalyzingth...再畢業設計做模型中要應用到SHELL181單元,那么這個單元有…

關于Set集合類你都知道什么?來自《卷Ⅰ》的靈魂提問

各位小伙伴們大家好,歡迎來到這個小扎扎的《Java核心技術 卷Ⅰ》筆記專欄,在這個系列專欄中我將記錄淺學這本書所得收獲,鑒于 看到就是學到、學到就是賺到 精神,這波簡直就是血賺 💡涉及的知識點速通🛫 關于…

流程圖虛線框表示什么_UI設計|APP的交互線框布局設計

一.流程圖設計流程圖(Flow Chart):用圖示的方式反映出特定主體為了滿足特定需求而進行的有特定邏輯關系的一系列操作過程。流程圖的四種基本結構:順序結構,條件結構(又稱選擇結構),循環結構,分支結構。1.流程圖的常用符…

使用Redis完成商品秒殺業務

各位小伙伴們大家好,歡迎來到這個小扎扎的Redis 6專欄,在這個系列專欄中我對B站黑馬的Redis教程進行一個總結,鑒于 看到就是學到、學到就是賺到 精神,這波依然是血賺 ┗|`O′|┛ 💡Redis知識點速覽&#…

表格列隱藏_【excel每日提升】Excel隱藏列,不讓別人打開!

【新朋友】點擊標題下面藍色字“王俊東“關注。 【老朋友】點擊右上角,轉發或分享本頁面內容。excel系列課程excel特效系列課程開始了,今天第2節!第1節:Excel有公式的單元格標記顏色,很簡單!第2節&#xf…

map與weakmap,ES6 Map和WeakMap有什么區別?

Looking this and this MDN pages it seems like the only difference between Maps and WeakMaps is a missing "size" property for WeakMaps. But is this true? Whats the difference between them?解決方案The experienced JavaScript programmer will notice…

“畢業季”|一個java開發實習生的OFFER之路

哈嘍哈嘍大家好,這里是小扎扎的博客。相信有關注過我的好盆友們可能會發現我已經有一段時間沒有出來劃水了,那么這段時間小扎扎都在干什么呢?沒錯!我確實是去找實習了!接下來就給大家介紹一下本次戰役的戰況如何 活動地…

virtualbox 該內存不能為written_系統提示“該內存不能為read”的原因和解決辦法...

我們單位的電腦經常顯示這個對話框,已經有好幾年了,單位的老頭們都不怎么懂電腦,我本人也不愛管閑事。但是出現這種對話框的原因是什么呢?又怎么解決呢?一般電腦經常出現藍屏和死機,而且頻繁出現。有時會出…

插件properties_Mybatis3系列 - 4. mybatis-config的properties屬性詳解

前兩章簡單的講解了MyBatis的使用方式. 接下來先全局的說一下MyBatis的全局的xml配置詳細說明.XML格式定義-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">configuration 的映射文件(根據定義順序說明)properties 屬性…

【Redis 6】秒殺業務——分布式鎖

各位小伙伴們大家好,歡迎來到這個小扎扎的Redis 6專欄,在這個系列專欄中我對B站黑馬的Redis教程進行一個總結,鑒于 看到就是學到、學到就是賺到 精神,這波依然是血賺 ┗|`O′|┛ 💡Redis知識點速覽&#…

python讀取文件最后幾行_如何用python獲取文件的最后一行,文件可能會比較大

展開全部 #!/usr/bin/env python import os import sys def get_last_n_lines(logfile, n): blk_size_max 4096 n_lines [] with open(logfile, rb) as fp: fp.seek(0, os.SEEK_END) cur_pos fp.tell() while cur_pos > 0 and len(n_lines) < n: blk_size min(blk_si…

360oauth token是什么意思_Oauth/access token

oauth/access_token第三放應用使用開始的request_token來換取用戶授權過的Access_tokenURL格式標準的OAuth http返回格式HTTP請求方式POST請求數限制false請求參數oauth_consumer_key: 創建應用時生成的APP KEY。oauth_token:經過用戶授權的Request Token。oauth_signature_met…

【Swagger】看這一篇就夠了

各位小伙伴們大家好&#xff0c;歡迎跟著小扎扎一起學習【Swagger】這門技術&#xff0c;在本片博客中我對B站狂神的Swagger教程進行一個總結&#xff0c;鑒于 看到就是學到、學到就是賺到 精神&#xff0c;這波依然是血賺 ┗|&#xff40;O′|┛ &#x1f4a1;Swagger知識點…

python mockito arg_that_wqingxiao

偶然間在脈脈上看到了一道頭條的算法面試題按照題目的理解&#xff0c;簡單的寫了一個html網頁pool開始{{index}}{{index}}var vm new Vue({el: #vue_det,data: {list: [],i: 0},methods: {details: function () {return this.site " - 學的不僅是技術&#xff0c;更是夢…

用python畫大雄_python制作斗圖生成器

網上各種帶文字的表情圖片都被大家玩壞了&#xff0c;今天就和大家一起用 python 親自做一個帶字表情圖片生成器。 不知道大家有沒有看到網上有很多人都在說 "人生苦短&#xff0c;我用 python"&#xff0c;這句話我之前也不是很理解&#xff0c;覺得人生苦短和用pyt…

【spring cloud】(一)使用idea創建可相互調用的多模塊應用

各位小伙伴們大家好&#xff0c;歡迎來到這個小扎扎的spring cloud專欄&#xff0c;在這個系列專欄中我對B站尚硅谷陽哥的spring cloud教程進行一個總結&#xff0c;鑒于 看到就是學到、學到就是賺到 精神&#xff0c;這波依然是血賺 ┗|&#xff40;O′|┛ &#x1f4a1;spr…

epson彩色打印機加墨水_愛普生打印機墨盒如何加墨?

展開全部掌握以下幾點步驟&#xff0c;即可輕松加墨。1、首先&#xff0c;從打印機上取下墨盒&#xff0c;32313133353236313431303231363533e4b893e5b19e31333365646234這里就不好做介紹了&#xff0c;取下墨盒的方法因機而異。將墨盒上的一層貼紙撕掉&#xff0c;并拿出所需材…

python字符串百分號_Python字符串格式化的2種方法

本文介紹了Python字符串格式化&#xff0c;主要有兩種方法&#xff0c;分享給大家&#xff0c;具體如下 用于字符串的拼接&#xff0c;性能更優。 字符串格式化有兩種方式&#xff1a;百分號方式、format方式。 百分號方式比較老&#xff0c;而format方式是比較先進的&#xff…