java 中的 數(shù)據(jù)結(jié)構(gòu)

java中常用的數(shù)據(jù)結(jié)構(gòu)

image.png

1:Array 數(shù)組

  1. 固定大小,數(shù)組的大小是初始化時(shí)決定無(wú)法修改的數(shù)值。
  2. 強(qiáng)類(lèi)型,存儲(chǔ)數(shù)據(jù)元素類(lèi)型必須在初始化時(shí)指定,因此在運(yùn)行時(shí),不需要耗費(fèi)額外的時(shí)間來(lái)定義數(shù)組類(lèi)型,能夠大大提升運(yùn)行效率。
  3. 可使用Foreach關(guān)鍵字實(shí)現(xiàn)數(shù)組迭代和查找。
    因?yàn)閿?shù)組大小是固定的,且是強(qiáng)類(lèi)型數(shù)據(jù)結(jié)構(gòu),因此在運(yùn)行時(shí)只占用很少的內(nèi)存,運(yùn)行時(shí)效率很高。

2:List

List接口為Collection直接接口。List所代表的是有序的Collection,即它用某種特定的插入順序來(lái)維護(hù)元素順序。用戶(hù)可以對(duì)列表中每個(gè)元素的插入位置進(jìn)行精確地控制,同時(shí)可以根據(jù)元素的整數(shù)索引(在列表中的位置)訪問(wèn)元素,并搜索列表中的元素。實(shí)現(xiàn)List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。

2.1:ArrayList

ArrayList是一個(gè)動(dòng)態(tài)數(shù)組,也是我們最常用的集合。它允許任何符合規(guī)則的元素插入甚至包括null。每一個(gè)ArrayList都有一個(gè)初始容量(10),該容量代表了數(shù)組的大小。隨著容器中的元素不斷增加,容器的大小也會(huì)隨著增加。在每次向容器中增加元素的同時(shí)都會(huì)進(jìn)行容量檢查,當(dāng)快溢出時(shí),就會(huì)進(jìn)行擴(kuò)容操作。所以如果我們明確所插入元素的多少,最好指定一個(gè)初始容量值,避免過(guò)多的進(jìn)行擴(kuò)容操作而浪費(fèi)時(shí)間、效率。size、isEmpty、get、set、iterator 和 listIterator 操作都以固定時(shí)間運(yùn)行。add 操作以分?jǐn)偟墓潭〞r(shí)間運(yùn)行,也就是說(shuō),添加 n 個(gè)元素需要 O(n) 時(shí)間(由于要考慮到擴(kuò)容,所以這不只是添加元素會(huì)帶來(lái)分?jǐn)偣潭〞r(shí)間開(kāi)銷(xiāo)那樣簡(jiǎn)單)。
ArrayList擅長(zhǎng)于隨機(jī)訪問(wèn)。同時(shí)ArrayList是非同步的。

2.2:LinkedList

同樣實(shí)現(xiàn)List接口的LinkedList與ArrayList不同,ArrayList是一個(gè)動(dòng)態(tài)數(shù)組,而LinkedList是一個(gè)雙向鏈表。所以它除了有ArrayList的基本操作方法外還額外提供了get,remove,insert方法在LinkedList的首部或尾部。
由于實(shí)現(xiàn)的方式不同,LinkedList不能隨機(jī)訪問(wèn),它所有的操作都是要按照雙重鏈表的需要執(zhí)行。在列表中索引的操作將從開(kāi)頭或結(jié)尾遍歷列表(從靠近指定索引的一端)。這樣做的好處就是可以通過(guò)較低的代價(jià)在List中進(jìn)行插入和刪除操作。
與ArrayList一樣,LinkedList也是非同步的。如果多個(gè)線(xiàn)程同時(shí)訪問(wèn)一個(gè)List,則必須自己實(shí)現(xiàn)訪問(wèn)同步。一種解決方法是在創(chuàng)建List時(shí)構(gòu)造一個(gè)同步的List:
List list = Collections.synchronizedList(new LinkedList(…));

2.3:Vector

與ArrayList相似,但是Vector是同步的。所以說(shuō)Vector是線(xiàn)程安全的動(dòng)態(tài)數(shù)組。它的操作與ArrayList幾乎一樣。

2.4:Stack

Stack繼承自Vector,實(shí)現(xiàn)一個(gè)后進(jìn)先出的堆棧。Stack提供5個(gè)額外的方法使得Vector得以被當(dāng)作堆棧使用。基本的push和pop 方法,還有peek方法得到棧頂?shù)脑?,empty方法測(cè)試堆棧是否為空,search方法檢測(cè)一個(gè)元素在堆棧中的位置。Stack剛創(chuàng)建后是空棧。

3: Set

et是一種不包括重復(fù)元素的Collection。它維持它自己的內(nèi)部排序,所以隨機(jī)訪問(wèn)沒(méi)有任何意義。與List一樣,它同樣運(yùn)行null的存在但是僅有一個(gè)。由于Set接口的特殊性,所有傳入Set集合中的元素都必須不同,同時(shí)要注意任何可變對(duì)象,如果在對(duì)集合中元素進(jìn)行操作時(shí),導(dǎo)致e1.equals(e2)==true,則必定會(huì)產(chǎn)生某些問(wèn)題。實(shí)現(xiàn)了Set接口的集合有:EnumSet、HashSet、TreeSet。

3.1、EnumSet

是枚舉的專(zhuān)用Set。所有的元素都是枚舉類(lèi)型。

3.2、HashSet

HashSet堪稱(chēng)查詢(xún)速度最快的集合,因?yàn)槠鋬?nèi)部是以HashCode來(lái)實(shí)現(xiàn)的。它內(nèi)部元素的順序是由哈希碼來(lái)決定的,所以它不保證set 的迭代順序;特別是它不保證該順序恒久不變。

3.3、TreeSet是有序的。

4:Map

Map與List、Set接口不同,它是由一系列鍵值對(duì)組成的集合,提供了key到Value的映射。同時(shí)它也沒(méi)有繼承Collection。在Map中它保證了key與value之間的一一對(duì)應(yīng)關(guān)系。也就是說(shuō)一個(gè)key對(duì)應(yīng)一個(gè)value,所以它不能存在相同的key值,當(dāng)然value值可以相同。實(shí)現(xiàn)map的有:HashMap、TreeMap、HashTable、Properties、EnumMap。

4.1、HashMap

以哈希表數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn),查找對(duì)象時(shí)通過(guò)哈希函數(shù)計(jì)算其位置,它是為快速查詢(xún)而設(shè)計(jì)的,其內(nèi)部定義了一個(gè)hash表數(shù)組(Entry[] table),元素會(huì)通過(guò)哈希轉(zhuǎn)換函數(shù)將元素的哈希地址轉(zhuǎn)換成數(shù)組中存放的索引,如果有沖突,則使用散列鏈表的形式將所有相同哈希地址的元素串起來(lái),可能通過(guò)查看HashMap.Entry的源碼它是一個(gè)單鏈表結(jié)構(gòu)。

4.2、TreeMap

鍵以某種排序規(guī)則排序,內(nèi)部以red-black(紅-黑)樹(shù)數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn),實(shí)現(xiàn)了SortedMap接口

4.3、HashTable

也是以哈希表數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的,解決沖突時(shí)與HashMap也一樣也是采用了散列鏈表的形式,不過(guò)性能比HashMap要低

5:Queue

隊(duì)列,它主要分為兩大類(lèi),一類(lèi)是阻塞式隊(duì)列,隊(duì)列滿(mǎn)了以后再插入元素則會(huì)拋出異常,主要包括ArrayBlockQueue、PriorityBlockingQueue、LinkedBlockingQueue。另一種隊(duì)列則是雙端隊(duì)列,支持在頭、尾兩端插入和移除元素,主要包括:ArrayDeque、LinkedBlockingDeque、LinkedList。

List

ArrayList

以數(shù)組實(shí)現(xiàn)。節(jié)約空間,但數(shù)組有容量限制。超出限制時(shí)會(huì)增加50%容量,用System.arraycopy()復(fù)制到新的數(shù)組。因此最好能給出數(shù)組大小的預(yù)估值。默認(rèn)第一次插入元素時(shí)創(chuàng)建大小為10的數(shù)組。

按數(shù)組下標(biāo)訪問(wèn)元素-get(i)、set(i,e) 的性能很高,這是數(shù)組的基本優(yōu)勢(shì)。

如果按下標(biāo)插入元素、刪除元素-add(i,e)、 remove(i)、remove(e),則要用System.arraycopy()來(lái)復(fù)制移動(dòng)部分受影響的元素,性能就變差了。

越是前面的元素,修改時(shí)要移動(dòng)的元素越多。直接在數(shù)組末尾加入元素-常用的add(e),刪除最后一個(gè)元素則無(wú)影響。

LinkedList

以雙向鏈表實(shí)現(xiàn)。鏈表無(wú)容量限制,但雙向鏈表本身使用了更多空間,每插入一個(gè)元素都要構(gòu)造一個(gè)額外的Node對(duì)象,也需要額外的鏈表指針操作。

按下標(biāo)訪問(wèn)元素-get(i)、set(i,e) 要悲劇的部分遍歷鏈表將指針移動(dòng)到位 (如果i>數(shù)組大小的一半,會(huì)從末尾移起)。

插入、刪除元素時(shí)修改前后節(jié)點(diǎn)的指針即可,不再需要復(fù)制移動(dòng)。但還是要部分遍歷鏈表的指針才能移動(dòng)到下標(biāo)所指的位置。

只有在鏈表兩頭的操作-add()、addFirst()、removeLast()或用iterator()上的remove()倒能省掉指針的移動(dòng)。

Apache Commons 有個(gè)TreeNodeList,里面是棵二叉樹(shù),可以快速移動(dòng)指針到位。

CopyOnWriteArrayList

并發(fā)優(yōu)化的ArrayList?;诓豢勺儗?duì)象策略,在修改時(shí)先復(fù)制出一個(gè)數(shù)組快照來(lái)修改,改好了,再讓內(nèi)部指針指向新數(shù)組。

因?yàn)閷?duì)快照的修改對(duì)讀操作來(lái)說(shuō)不可見(jiàn),所以讀讀之間不互斥,讀寫(xiě)之間也不互斥,只有寫(xiě)寫(xiě)之間要加鎖互斥。但復(fù)制快照的成本昂貴,典型的適合讀多寫(xiě)少的場(chǎng)景。

雖然增加了addIfAbsent(e)方法,會(huì)遍歷數(shù)組來(lái)檢查元素是否已存在,性能可想像的不會(huì)太好。

遺憾

無(wú)論哪種實(shí)現(xiàn),按值返回下標(biāo)contains(e), indexOf(e), remove(e) 都需遍歷所有元素進(jìn)行比較,性能可想像的不會(huì)太好。

沒(méi)有按元素值排序的SortedList。

除了CopyOnWriteArrayList,再?zèng)]有其他線(xiàn)程安全又并發(fā)優(yōu)化的實(shí)現(xiàn)如ConcurrentLinkedList。湊合著用Set與Queue中的等價(jià)類(lèi)時(shí),會(huì)缺少一些List特有的方法如get(i)。如果更新頻率較高,或數(shù)組較大時(shí),還是得用Collections.synchronizedList(list),對(duì)所有操作用同一把鎖來(lái)保證線(xiàn)程安全。

Map

HashMap

以Entry[]數(shù)組實(shí)現(xiàn)的哈希桶數(shù)組,用Key的哈希值取模桶數(shù)組的大小可得到數(shù)組下標(biāo)。

插入元素時(shí),如果兩條Key落在同一個(gè)桶(比如哈希值1和17取模16后都屬于第一個(gè)哈希桶),我們稱(chēng)之為哈希沖突。

JDK的做法是鏈表法,Entry用一個(gè)next屬性實(shí)現(xiàn)多個(gè)Entry以單向鏈表存放。查找哈希值為17的key時(shí),先定位到哈希桶,然后鏈表遍歷桶里所有元素,逐個(gè)比較其Hash值然后key值。

在JDK8里,新增默認(rèn)為8的閾值,當(dāng)一個(gè)桶里的Entry超過(guò)閥值,就不以單向鏈表而以紅黑樹(shù)來(lái)存放以加快Key的查找速度。

當(dāng)然,最好還是桶里只有一個(gè)元素,不用去比較。所以默認(rèn)當(dāng)Entry數(shù)量達(dá)到桶數(shù)量的75%時(shí),哈希沖突已比較嚴(yán)重,就會(huì)成倍擴(kuò)容桶數(shù)組,并重新分配所有原來(lái)的Entry。擴(kuò)容成本不低,所以也最好有個(gè)預(yù)估值。

取模用與操作(hash & (arrayLength-1))會(huì)比較快,所以數(shù)組的大小永遠(yuǎn)是2的N次方, 你隨便給一個(gè)初始值比如17會(huì)轉(zhuǎn)為32。默認(rèn)第一次放入元素時(shí)的初始值是16。

iterator()時(shí)順著哈希桶數(shù)組來(lái)遍歷,看起來(lái)是個(gè)亂序。

LinkedHashMap

擴(kuò)展HashMap,每個(gè)Entry增加雙向鏈表,號(hào)稱(chēng)是最占內(nèi)存的數(shù)據(jù)結(jié)構(gòu)。

支持iterator()時(shí)按Entry的插入順序來(lái)排序(如果設(shè)置accessOrder屬性為true,則所有讀寫(xiě)訪問(wèn)都排序)。

插入時(shí),Entry把自己加到Header Entry的前面去。如果所有讀寫(xiě)訪問(wèn)都要排序,還要把前后Entry的before/after拼接起來(lái)以在鏈表中刪除掉自己,所以此時(shí)讀操作也是線(xiàn)程不安全的了。

TreeMap

以紅黑樹(shù)實(shí)現(xiàn),紅黑樹(shù)又叫自平衡二叉樹(shù):

對(duì)于任一節(jié)點(diǎn)而言,其到葉節(jié)點(diǎn)的每一條路徑都包含相同數(shù)目的黑結(jié)點(diǎn)。
上面的規(guī)定,使得樹(shù)的層數(shù)不會(huì)差的太遠(yuǎn),使得所有操作的復(fù)雜度不超過(guò) O(lgn),但也使得插入,修改時(shí)要復(fù)雜的左旋右旋來(lái)保持樹(shù)的平衡。

支持iterator()時(shí)按Key值排序,可按實(shí)現(xiàn)了Comparable接口的Key的升序排序,或由傳入的Comparator控制??上胂蟮?,在樹(shù)上插入/刪除元素的代價(jià)一定比HashMap的大。

支持SortedMap接口,如firstKey(),lastKey()取得最大最小的key,或sub(fromKey, toKey), tailMap(fromKey)剪取Map的某一段。

EnumMap

EnumMap的原理是,在構(gòu)造函數(shù)里要傳入枚舉類(lèi),那它就構(gòu)建一個(gè)與枚舉的所有值等大的數(shù)組,按Enum. ordinal()下標(biāo)來(lái)訪問(wèn)數(shù)組。性能與內(nèi)存占用俱佳。

美中不足的是,因?yàn)橐獙?shí)現(xiàn)Map接口,而 V get(Object key)中key是Object而不是泛型K,所以安全起見(jiàn),EnumMap每次訪問(wèn)都要先對(duì)Key進(jìn)行類(lèi)型判斷,在JMC里錄得不低的采樣命中頻率。

ConcurrentHashMap

并發(fā)優(yōu)化的HashMap。

在JDK5里的經(jīng)典設(shè)計(jì),默認(rèn)16把寫(xiě)鎖(可以設(shè)置更多),有效分散了阻塞的概率。數(shù)據(jù)結(jié)構(gòu)為Segment[],每個(gè)Segment一把鎖。Segment里面才是哈希桶數(shù)組。Key先算出它在哪個(gè)Segment里,再去算它在哪個(gè)哈希桶里。

也沒(méi)有讀鎖,因?yàn)閜ut/remove動(dòng)作是個(gè)原子動(dòng)作(比如put的整個(gè)過(guò)程是一個(gè)對(duì)數(shù)組元素/Entry 指針的賦值操作),讀操作不會(huì)看到一個(gè)更新動(dòng)作的中間狀態(tài)。

但在JDK8里,Segment[]的設(shè)計(jì)被拋棄了,改為精心設(shè)計(jì)的,只在需要鎖的時(shí)候加鎖。

支持ConcurrentMap接口,如putIfAbsent(key,value)與相反的replace(key,value)與以及實(shí)現(xiàn)CAS的replace(key, oldValue, newValue)。

ConcurrentSkipListMap

JDK6新增的并發(fā)優(yōu)化的SortedMap,以SkipList結(jié)構(gòu)實(shí)現(xiàn)。Concurrent包選用它是因?yàn)樗С只贑AS的無(wú)鎖算法,而紅黑樹(shù)則沒(méi)有好的無(wú)鎖算法。

原理上,可以想象為多個(gè)鏈表組成的N層樓,其中的元素從稀疏到密集,每個(gè)元素有往右與往下的指針。從第一層樓開(kāi)始遍歷,如果右端的值比期望的大,那就往下走一層,繼續(xù)往前走。

典型的空間換時(shí)間。每次插入,都要決定在哪幾層插入,同時(shí),要決定要不要多蓋一層樓。

它的size()同樣不能隨便調(diào),會(huì)遍歷來(lái)統(tǒng)計(jì)。

Set

所有Set幾乎都是內(nèi)部用一個(gè)Map來(lái)實(shí)現(xiàn), 因?yàn)镸ap里的KeySet就是一個(gè)Set,而value是假值,全部使用同一個(gè)Object即可。

Set的特征也繼承了那些內(nèi)部的Map實(shí)現(xiàn)的特征。

HashSet:內(nèi)部是HashMap。

LinkedHashSet:內(nèi)部是LinkedHashMap。

TreeSet:內(nèi)部是TreeMap的SortedSet。

ConcurrentSkipListSet:內(nèi)部是ConcurrentSkipListMap的并發(fā)優(yōu)化的SortedSet。

CopyOnWriteArraySet:內(nèi)部是CopyOnWriteArrayList的并發(fā)優(yōu)化的Set,利用其addIfAbsent()方法實(shí)現(xiàn)元素去重,如前所述該方法的性能很一般。

好像少了個(gè)ConcurrentHashSet,本來(lái)也該有一個(gè)內(nèi)部用ConcurrentHashMap的簡(jiǎn)單實(shí)現(xiàn),但JDK偏偏沒(méi)提供。Jetty就自己簡(jiǎn)單封了一個(gè),Guava則直接用java.util.Collections.newSetFromMap(new ConcurrentHashMap()) 實(shí)現(xiàn)。

Queue

Queue是在兩端出入的List,所以也可以用數(shù)組或鏈表來(lái)實(shí)現(xiàn)。

普通隊(duì)列

LinkedList
是的,以雙向鏈表實(shí)現(xiàn)的LinkedList既是List,也是Queue。

ArrayDeque
以循環(huán)數(shù)組實(shí)現(xiàn)的雙向Queue。大小是2的倍數(shù),默認(rèn)是16。

為了支持FIFO,即從數(shù)組尾壓入元素(快),從數(shù)組頭取出元素(超慢),就不能再使用普通ArrayList的實(shí)現(xiàn)了,改為使用循環(huán)數(shù)組。

有隊(duì)頭隊(duì)尾兩個(gè)下標(biāo):彈出元素時(shí),隊(duì)頭下標(biāo)遞增;加入元素時(shí),隊(duì)尾下標(biāo)遞增。如果加入元素時(shí)已到數(shù)組空間的末尾,則將元素賦值到數(shù)組[0],同時(shí)隊(duì)尾下標(biāo)指向0,再插入下一個(gè)元素則賦值到數(shù)組[1],隊(duì)尾下標(biāo)指向1。如果隊(duì)尾的下標(biāo)追上隊(duì)頭,說(shuō)明數(shù)組所有空間已用完,進(jìn)行雙倍的數(shù)組擴(kuò)容。

PriorityQueue

用平衡二叉最小堆實(shí)現(xiàn)的優(yōu)先級(jí)隊(duì)列,不再是FIFO,而是按元素實(shí)現(xiàn)的Comparable接口或傳入Comparator的比較結(jié)果來(lái)出隊(duì),數(shù)值越小,優(yōu)先級(jí)越高,越先出隊(duì)。但是注意其iterator()的返回不會(huì)排序。

平衡最小二叉堆,用一個(gè)簡(jiǎn)單的數(shù)組即可表達(dá),可以快速尋址,沒(méi)有指針什么的。最小的在queue[0] ,比如queue[4]的兩個(gè)孩子,會(huì)在queue[24+1] 和 queue[2(4+1)],即queue[9]和queue[10]。

入隊(duì)時(shí),插入queue[size],然后二叉地往上比較調(diào)整堆。

出隊(duì)時(shí),彈出queue[0],然后把queque[size]拿出來(lái)二叉地往下比較調(diào)整堆。

初始大小為11,空間不夠時(shí)自動(dòng)50%擴(kuò)容。

線(xiàn)程安全的隊(duì)列

ConcurrentLinkedQueue/Deque
無(wú)界的并發(fā)優(yōu)化的Queue,基于鏈表,實(shí)現(xiàn)了依賴(lài)于CAS的無(wú)鎖算法。

ConcurrentLinkedQueue的結(jié)構(gòu)是單向鏈表和head/tail兩個(gè)指針,因?yàn)槿腙?duì)時(shí)需要修改隊(duì)尾元素的next指針,以及修改tail指向新入隊(duì)的元素兩個(gè)CAS動(dòng)作無(wú)法原子,所以需要的特殊的算法。

線(xiàn)程安全的阻塞隊(duì)列

BlockingQueue,一來(lái)如果隊(duì)列已空不用重復(fù)的查看是否有新數(shù)據(jù)而會(huì)阻塞在那里,二來(lái)隊(duì)列的長(zhǎng)度受限,用以保證生產(chǎn)者與消費(fèi)者的速度不會(huì)相差太遠(yuǎn)。當(dāng)入隊(duì)時(shí)隊(duì)列已滿(mǎn),或出隊(duì)時(shí)隊(duì)列已空,不同函數(shù)的效果見(jiàn)下表

ArrayBlockingQueue
定長(zhǎng)的并發(fā)優(yōu)化的BlockingQueue,也是基于循環(huán)數(shù)組實(shí)現(xiàn)。有一把公共的鎖與notFull、notEmpty兩個(gè)Condition管理隊(duì)列滿(mǎn)或空時(shí)的阻塞狀態(tài)。

LinkedBlockingQueue/Deque
可選定長(zhǎng)的并發(fā)優(yōu)化的BlockingQueue,基于鏈表實(shí)現(xiàn),所以可以把長(zhǎng)度設(shè)為Integer.MAX_VALUE成為無(wú)界無(wú)等待的。

利用鏈表的特征,分離了takeLock與putLock兩把鎖,繼續(xù)用notEmpty、notFull管理隊(duì)列滿(mǎn)或空時(shí)的阻塞狀態(tài)。

PriorityBlockingQueue
無(wú)界的PriorityQueue,也是基于數(shù)組存儲(chǔ)的二叉堆(見(jiàn)前)。一把公共的鎖實(shí)現(xiàn)線(xiàn)程安全。因?yàn)闊o(wú)界,空間不夠時(shí)會(huì)自動(dòng)擴(kuò)容,所以入列時(shí)不會(huì)鎖,出列為空時(shí)才會(huì)鎖。

DelayQueue
內(nèi)部包含一個(gè)PriorityQueue,同樣是無(wú)界的,同樣是出列時(shí)才會(huì)鎖。一把公共的鎖實(shí)現(xiàn)線(xiàn)程安全。元素需實(shí)現(xiàn)Delayed接口,每次調(diào)用時(shí)需返回當(dāng)前離觸發(fā)時(shí)間還有多久,小于0表示該觸發(fā)了。

pull()時(shí)會(huì)用peek()查看隊(duì)頭的元素,檢查是否到達(dá)觸發(fā)時(shí)間。ScheduledThreadPoolExecutor用了類(lèi)似的結(jié)構(gòu)。

同步隊(duì)列

SynchronousQueue同步隊(duì)列本身無(wú)容量,放入元素時(shí),比如等待元素被另一條線(xiàn)程的消費(fèi)者取走再返回。JDK線(xiàn)程池里用它。

JDK7還有個(gè)LinkedTransferQueue,在普通線(xiàn)程安全的BlockingQueue的基礎(chǔ)上,增加一個(gè)transfer(e) 函數(shù),效果與SynchronousQueue一樣。

參考:
https://blog.csdn.net/a724888/article/details/80215706
https://blog.csdn.net/weixin_42158424/article/details/80231642
https://www.runoob.com/java/java-collections.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 編程好比是一輛汽車(chē),而數(shù)據(jù)結(jié)構(gòu)和算法是汽車(chē)內(nèi)部的變速箱。一個(gè)開(kāi)車(chē)的人不懂變速箱的原理也是能開(kāi)車(chē)的,同理一個(gè)不懂?dāng)?shù)據(jù)...
    java架構(gòu)源閱讀 696評(píng)論 0 4
  • 最近在整理數(shù)據(jù)結(jié)構(gòu)方面的知識(shí), 系統(tǒng)化看了下Java中常用數(shù)據(jù)結(jié)構(gòu), 突發(fā)奇想用動(dòng)畫(huà)來(lái)繪制數(shù)據(jù)流轉(zhuǎn)過(guò)程。 主要基于...
    程序員BUG閱讀 536評(píng)論 0 2
  • 前言 之前遇到一個(gè)問(wèn)題,具體是說(shuō): 當(dāng)我們用HashMap的時(shí)候,是怎樣考慮優(yōu)化其性能的呢?當(dāng)時(shí)就一臉懵逼,原來(lái)是...
    neko_nia閱讀 735評(píng)論 0 6
  • 久違的晴天,家長(zhǎng)會(huì)。 家長(zhǎng)大會(huì)開(kāi)好到教室時(shí),離放學(xué)已經(jīng)沒(méi)多少時(shí)間了。班主任說(shuō)已經(jīng)安排了三個(gè)家長(zhǎng)分享經(jīng)驗(yàn)。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,867評(píng)論 16 22
  • 今天感恩節(jié)哎,感謝一直在我身邊的親朋好友。感恩相遇!感恩不離不棄。 中午開(kāi)了第一次的黨會(huì),身份的轉(zhuǎn)變要...
    余生動(dòng)聽(tīng)閱讀 10,916評(píng)論 0 11

友情鏈接更多精彩內(nèi)容