集合--基礎(chǔ)知識(shí)

集合

集合類(lèi)是一種工具類(lèi),存儲(chǔ)數(shù)量不等的對(duì)象击儡,可以實(shí)現(xiàn)棧塔沃,隊(duì)列等數(shù)據(jù)結(jié)構(gòu)⊙舻可以分為:Set:無(wú)序蛀柴,不可重復(fù)的集合; List:有序矫夯,重復(fù)的集合鸽疾; Queue:隊(duì)列集合實(shí)現(xiàn); Map:具有映射關(guān)系的集合 四種训貌。
集合類(lèi)主要由:Collection和Map兩個(gè)接口派生而出.
Map保存的的每項(xiàng)數(shù)據(jù)都是由key-value對(duì)即兩個(gè)值組成制肮,key用來(lái)標(biāo)識(shí)集合里面的每項(xiàng)數(shù)據(jù)并且不可以重復(fù),根據(jù)key值來(lái)獲取value數(shù)據(jù)递沪。

Stream

對(duì)java集合進(jìn)行操作豺鼻,將要處理的集合的元素看成一種流,流在管道中傳輸款慨,在管道的節(jié)點(diǎn)上進(jìn)行處理儒飒,并支持聚合操作。stream的聚合檩奠、消費(fèi)或收集操作只能進(jìn)行一次桩了,再次操作會(huì)報(bào)錯(cuò)。

Set集合

Set集合不能記住元素的添加順序埠戳,不允許包含重復(fù)元素井誉。
所有Set接口的內(nèi)部都是Map做支撐,

  1. HashSet

按照Hash算法來(lái)存儲(chǔ)集合中的元素乞而,底層的數(shù)據(jù)結(jié)構(gòu)是Hash表送悔。
HashSet不是同步的。集合的元素值可以是空爪模。
根據(jù)hashCode值決定元素在集合中的存儲(chǔ)位置欠啤,HashSet判斷兩個(gè)對(duì)象相等的標(biāo)準(zhǔn):兩個(gè)對(duì)象通過(guò)equals()方法比較相等,并且兩個(gè)對(duì)象的hashCode()方法返回值也相等屋灌。

兩個(gè)對(duì)象的hashCode值不同洁段,但是兩個(gè)對(duì)象的equals()方法返回相同,會(huì)把兩個(gè)對(duì)象保存在hash表的不同位置共郭。
兩個(gè)對(duì)象hashCode值相同祠丝,但是equals()方法比較不同疾呻,會(huì)在同一個(gè)位置用鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)保存多個(gè)對(duì)象。
重寫(xiě)hashCode()方法的基本規(guī)則
兩個(gè)對(duì)象通過(guò)equals()方法比較返回true写半,這兩個(gè)對(duì)象的hashCode值也應(yīng)該相同岸蜗。

LinkedHashSet:是HashSet的子類(lèi)。也是根據(jù)hashCode值來(lái)決定元素在集合中的存儲(chǔ)位置叠蝇。使用雙重鏈表維護(hù)元素的插入次序璃岳。遍歷集合中的元素時(shí)會(huì)按元素的添加順序來(lái)訪(fǎng)問(wèn)集合中的元素。

  1. TreeSet

是SortedSet接口的實(shí)現(xiàn)類(lèi)悔捶,可以確保集合元素處于排序狀態(tài)铃慷。不是根據(jù)元素的插入順序進(jìn)行排序,根據(jù)實(shí)際值的大小進(jìn)行排序蜕该。
TreeSet采用紅黑樹(shù)的數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)集合元素犁柜。分為自然排序和定制排序。
自然排序:TreeSet調(diào)用集合元素的comparaTo()方法來(lái)比較元素之間的大小堂淡,然后按升序排列馋缅。敲重點(diǎn):1. 加入TreeSet的元素都要實(shí)現(xiàn)Comparable接口 2.加入的最好都是同一個(gè)類(lèi)型的元素。3. 兩個(gè)元素相等的依據(jù)是兩個(gè)對(duì)象的comparaTo()方法返回為0淤齐;4. 注意不要修改可變對(duì)象的實(shí)例變量股囊。
兩個(gè)對(duì)象通過(guò)equals()方法返回true時(shí),兩個(gè)對(duì)象的comparaTo()方法比較應(yīng)返回0更啄。

定制排序:在創(chuàng)建TreeSet集合時(shí)稚疹,創(chuàng)建一個(gè)Comparator對(duì)象,與TreeSet集合關(guān)聯(lián)祭务,Comparator負(fù)責(zé)排序邏輯内狗,通過(guò)Comparator接口的幫助,通過(guò)利用該函數(shù)式接口的compara()方法來(lái)實(shí)現(xiàn)义锥。

  1. EnumSet

為枚舉類(lèi)設(shè)計(jì)的集合類(lèi)柳沙,所有元素必須是指定枚舉類(lèi)型的枚舉值。是有序的集合拌倍,以枚舉值在Enum類(lèi)中的定義順序來(lái)決定集合元素的順序赂鲤。不允許加入null元素。EnumSet沒(méi)有暴露任何構(gòu)造器來(lái)創(chuàng)建該類(lèi)的實(shí)例柱恤。
這三個(gè)Set的實(shí)現(xiàn)類(lèi)都是線(xiàn)程不安全的数初。

List集合

代表元素有序可以重復(fù)的集合。每個(gè)元素都有其對(duì)應(yīng)的順序索引梗顺,通過(guò)索引來(lái)訪(fǎng)問(wèn)指定位置的元素泡孩。List判斷兩個(gè)對(duì)象相等的標(biāo)準(zhǔn):通過(guò)equals()方法比較返回true即可。

List的listIterator()方法:返回一個(gè)ListIterator對(duì)象寺谤,ListIterator接口繼承自Iterator接口仑鸥,提供了操作List集合的方法吮播。ListIterator增加了向前迭代的功能,還可以向List集合里面添加元素眼俊。
兩個(gè)實(shí)現(xiàn)類(lèi):ArrayList和Vector意狠,都是基于數(shù)組實(shí)現(xiàn)的List類(lèi)。封裝了一個(gè)動(dòng)態(tài)的疮胖,允許再分配的Object[]數(shù)組摄职,可以設(shè)置數(shù)組的長(zhǎng)度,當(dāng)數(shù)組中的元素超過(guò)設(shè)置的數(shù)組長(zhǎng)度時(shí)获列,數(shù)組長(zhǎng)度會(huì)增加
創(chuàng)建時(shí)不指定集合的大小時(shí)蛔垢,動(dòng)態(tài)的Object[]數(shù)組的長(zhǎng)度默認(rèn)為10击孩。

ArrayList:是線(xiàn)程不安全的,
Vector:是線(xiàn)程安全的鹏漆,性能低于A(yíng)rrayList巩梢。

ArrayDeque也是List的實(shí)現(xiàn)類(lèi),同時(shí)也實(shí)現(xiàn)了Deque接口艺玲。實(shí)現(xiàn)了Deque接口括蝠,因此可以當(dāng)作棧來(lái)使用,它的底層也是基于數(shù)組的實(shí)現(xiàn)饭聚。

Queue集合

用于模擬隊(duì)列這種數(shù)據(jù)結(jié)構(gòu)忌警。

  1. PriorityQueue

隊(duì)列的實(shí)現(xiàn)類(lèi),保存隊(duì)列元素的順序不是按加入隊(duì)列的順序秒梳,是按照隊(duì)列元素的大小進(jìn)行重新排序法绵。不允許加入null元素。有兩種排序方式:自然排序和定制排序酪碘。

  1. Deque接口

是Queue接口的子接口朋譬,代表一個(gè)雙端隊(duì)列。包含一些棧方法兴垦。
ArrayDeque:基于數(shù)組實(shí)現(xiàn)的雙端隊(duì)列徙赢。可以當(dāng)作棧來(lái)使用探越。

  1. LinkedList

是List接口的實(shí)現(xiàn)類(lèi)狡赐,還實(shí)現(xiàn)了Deque接口。內(nèi)部以鏈表的形式來(lái)保存集合中的元素扶关。
提供了List的功能阴汇,還提供了雙端隊(duì)列和棧的功能。

Map集合

保存具有映射關(guān)系的數(shù)據(jù)节槐,集合里面保存著兩組值搀庶,一組用于保存key拐纱,另一組保存value,key和value都可以是任何引用類(lèi)型的數(shù)據(jù)哥倔。key不允許重復(fù)秸架。key集的存儲(chǔ)形式和Set集合中元素的存儲(chǔ)形式相似。Map提供了一個(gè)Entry內(nèi)部類(lèi)來(lái)封裝key-value對(duì)咆蒿,在計(jì)算Entry存儲(chǔ)時(shí)只考慮Entry封裝的key东抹。

  1. HashMap
    線(xiàn)程不安全的實(shí)現(xiàn)。允許使用null值作為key和value沃测。
  2. Hashtable
    線(xiàn)程安全的Map實(shí)現(xiàn)缭黔。不允許使用null值作為key和value。

HashMap和Hashtable中用作key的對(duì)象必須實(shí)現(xiàn)hashCode()方法和equals()方法蒂破,并且這兩個(gè)map集合也不能保證其中的key-value的順序馏谨。1. 判斷key值相等的標(biāo)準(zhǔn):通過(guò)equals()方法返回true,hashCode值也相等附迷。2. 判斷兩個(gè)value相等的標(biāo)準(zhǔn):只要兩個(gè)對(duì)象通過(guò)equals()方法比較返回true

  1. LinkedHashMap
    是HashMap的子類(lèi)惧互。使用雙向鏈表來(lái)維護(hù)key-value對(duì)的次序,與插入順序保持一致喇伯。
  2. Properties
    是Hashtable的子類(lèi)喊儡。處理屬性文件,將map對(duì)象和屬性文件關(guān)聯(lián)起來(lái)稻据。相對(duì)于key,value都是String類(lèi)型的Map艾猜。
  3. SortedMap接口和TreeMap實(shí)現(xiàn)類(lèi)
    TreeMap是一個(gè)紅黑樹(shù)數(shù)據(jù)結(jié)構(gòu)。key-value對(duì)作為紅黑樹(shù)的一個(gè)節(jié)點(diǎn)攀甚,在存儲(chǔ)key-value對(duì)時(shí)箩朴,會(huì)根據(jù)key對(duì)節(jié)點(diǎn)進(jìn)行排序
    自然排序
    定制排序·
  4. WeakHashMap
    key的類(lèi)型是WeakRerfence秋度,key被回收炸庞,key對(duì)應(yīng)的指向的對(duì)象會(huì)被從Map容器中移除。
  5. IdentityHashMap
    實(shí)現(xiàn)機(jī)制與HashMap基本相似荚斯,但在處理兩個(gè)key相等時(shí):要求兩個(gè)key嚴(yán)格相等時(shí)才認(rèn)為兩個(gè)key相等埠居。
  6. EnumHashMap
    在內(nèi)部以數(shù)組形式存儲(chǔ)。不允許使用null作為key事期。
HashSet與HashMap

HashSet采用hash算法來(lái)決定集合中元素的存儲(chǔ)位置滥壕,通過(guò)hash算法控制集合的大小。
HashMap類(lèi)似HashSet兽泣,采用hash算法決定集合中key的存儲(chǔ)位置绎橘,也通過(guò)hash算法來(lái)增加key集合的大小。

遍歷集合
  1. Iterable接口的forEach()方法來(lái)遍歷集合:傳給該方法的參數(shù)是一個(gè)目標(biāo)類(lèi)型為Consumer類(lèi)型的Lambda表達(dá)式。
  2. Iterator遍歷集合元素:

Iterator對(duì)象是迭代器称鳞,必須依附于Collection對(duì)象涮较。
Iterator遍歷集合時(shí),不是將集合元素本身傳給了Iterator迭代變量冈止,是將集合元素的值傳給了迭代變量狂票。
Iterator迭代訪(fǎng)問(wèn)集合的元素時(shí),集合里的元素不能被改變熙暴,否則會(huì)引發(fā)ConcurrentModificationException異常闺属。只有使用Iterator的remove()方法刪除上一次next()方法返回的集合元素才可以。

Iterator采用快速失敗機(jī)制(fail-fast)周霉,在迭代過(guò)程中檢測(cè)到集合元素已經(jīng)被修改掂器,立即引發(fā)ConcurrentModification異常。

快速失敗機(jī)制(fail-fast)
對(duì)集合修改次數(shù)的期望值
對(duì)集合的修改次數(shù):每次調(diào)用集合的add()方法或者remove()方法就會(huì)將該值加1或者減1俱箱。
修改次數(shù)的期望值剛剛開(kāi)始時(shí)是等于修改次數(shù)的唉匾。

檢查修改次數(shù)和修改次數(shù)的期望值是否相等,不等時(shí)拋出ConcurrentModificationException異常匠楚。

在Iterator的next()方法中,先會(huì)檢查修改次數(shù)和修改次數(shù)的期望值是否相等厂财,然后再得到集合里的下一個(gè)元素芋簿。

在Iterator實(shí)現(xiàn)類(lèi)的remove()方法中,刪除一個(gè)元素時(shí)璃饱,是調(diào)用集合自己的刪除函數(shù)与斤,并會(huì)將修改次數(shù)加一,并將修改次數(shù)的值賦值給修改次數(shù)的期望值荚恶。
沒(méi)有調(diào)用Iterator的remove()方法進(jìn)行刪除操作撩穿,使用集合的刪除函數(shù)來(lái)進(jìn)行刪除操作時(shí),修改次數(shù)會(huì)加1谒撼,但是不會(huì)將修改次數(shù)的值賦值為修改次數(shù)的期望值食寡,導(dǎo)致修改次數(shù)的值和修改次數(shù)期望值的值不一致,在進(jìn)行下一次next()迭代時(shí)廓潜,會(huì)檢測(cè)出兩者不相等抵皱,然后拋出ConcurrentModificationException異常。

單線(xiàn)程環(huán)境下:將使用集合進(jìn)行刪除操作修改為使用Iterator對(duì)象進(jìn)行刪除就會(huì)正確辩蛋,不會(huì)拋出異常呻畸。
多線(xiàn)程環(huán)境下:就是使用Iterator的刪除函數(shù)進(jìn)行刪除也還是會(huì)拋出異常。
因?yàn)樵诙嗑€(xiàn)程環(huán)境下悼院,每個(gè)線(xiàn)程是不同的Iterator對(duì)象伤为,修改次數(shù)的期望值是線(xiàn)程私有的,修改次數(shù)是共享的据途。
當(dāng)一個(gè)線(xiàn)程使用Iterator對(duì)象進(jìn)行remove()刪除時(shí)绞愚,這時(shí)候共享的修改次數(shù)值和這個(gè)線(xiàn)程的修改次數(shù)期望值都會(huì)自增叙甸;但是其他線(xiàn)程的私有的修改次數(shù)期望值沒(méi)有自增,所以其他線(xiàn)程就會(huì)拋出ConcurrentModificationException異常了爽醋。

  1. Lambda表達(dá)式遍歷:類(lèi)似第一種蚁署。
  2. foreach循環(huán)遍歷

迭代變量是集合元素的值,不是集合本身蚂四。
使用循環(huán)進(jìn)行遍歷時(shí)光戈,也不能改變集合,否則會(huì)引發(fā)ConcurrentModificationException異常遂赠。

Hash算法

散列表
也叫哈希表久妆,基于高速存取角度設(shè)計(jì)的,是以空間換時(shí)間跷睦,其中的元素不是緊密排列的筷弦,可能存在空隙。
以一種鍵-值(key-indexed)存儲(chǔ)數(shù)據(jù)的結(jié)構(gòu)抑诸,輸入key烂琴,可查找到對(duì)應(yīng)的值。

通過(guò)關(guān)鍵碼值(key)直接進(jìn)行訪(fǎng)問(wèn)存放記錄(indexed值)的數(shù)組(散列表)蜕乡。把關(guān)鍵碼值通過(guò)映射函數(shù)(散列函數(shù))映射到散列表中的一個(gè)位置來(lái)訪(fǎng)問(wèn)散列表中的記錄奸绷。
表中存儲(chǔ)元素的位置稱(chēng)為

哈希表包含的屬性
容量(capacity):表中桶的數(shù)量层玲。
初始化容量:創(chuàng)建哈希表時(shí)桶的數(shù)量号醉。
尺寸:當(dāng)前哈希表中記錄的數(shù)量。
負(fù)載因子:等于尺寸/容量辛块。
負(fù)載極限:是一個(gè)0-1的數(shù)值畔派。默認(rèn)的負(fù)載極限為0.75。決定了hash表的最大填滿(mǎn)程度润绵。當(dāng)負(fù)載因子達(dá)到負(fù)載極限時(shí)线椰,哈希表會(huì)自動(dòng)成倍的增加桶的數(shù)量,并會(huì)將原有的對(duì)象重新分配尘盼,放入新的桶中士嚎。

hash沖突
兩個(gè)元素通過(guò)映射函數(shù)得到的在散列表中的存儲(chǔ)位置相同。
發(fā)生沖突的兩個(gè)元素稱(chēng)為同義詞悔叽。

解決沖突
取決于3點(diǎn):
a.散列函數(shù)莱衩,散列函數(shù)計(jì)算得到的表中的存儲(chǔ)位置應(yīng)平均分布。
b.處理沖突的方法娇澎。
c.負(fù)載因子的大小笨蚁。
方法:
a.線(xiàn)性探測(cè)法:沖突后,線(xiàn)性向前探測(cè),找到最近的一個(gè)空位置括细。
b.雙散列函數(shù)法:

CopyOnWriteArrayList
HashSet同步
LinkedHashSet的底層的鏈表

  • ClassCastException:JVM在檢測(cè)到兩個(gè)類(lèi)型間轉(zhuǎn)換不兼容時(shí)引發(fā)的運(yùn)行時(shí)異常伪很。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市奋单,隨后出現(xiàn)的幾起案子锉试,更是在濱河造成了極大的恐慌,老刑警劉巖览濒,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呆盖,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡贷笛,警方通過(guò)查閱死者的電腦和手機(jī)应又,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)乏苦,“玉大人株扛,你說(shuō)我怎么就攤上這事』慵觯” “怎么了洞就?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)掀淘。 經(jīng)常有香客問(wèn)我奖磁,道長(zhǎng),這世上最難降的妖魔是什么繁疤? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮秕狰,結(jié)果婚禮上稠腊,老公的妹妹穿的比我還像新娘。我一直安慰自己鸣哀,他們只是感情好架忌,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著我衬,像睡著了一般叹放。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挠羔,一...
    開(kāi)封第一講書(shū)人閱讀 49,829評(píng)論 1 290
  • 那天井仰,我揣著相機(jī)與錄音,去河邊找鬼破加。 笑死俱恶,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播合是,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼了罪,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了聪全?” 一聲冷哼從身側(cè)響起泊藕,我...
    開(kāi)封第一講書(shū)人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎难礼,沒(méi)想到半個(gè)月后娃圆,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鹤竭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年踊餐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片臀稚。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吝岭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吧寺,到底是詐尸還是另有隱情窜管,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布稚机,位于F島的核電站幕帆,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏赖条。R本人自食惡果不足惜失乾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望纬乍。 院中可真熱鬧碱茁,春花似錦、人聲如沸仿贬。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)茧泪。三九已至蜓氨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間队伟,已是汗流浹背穴吹。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嗜侮,地道東北人刀荒。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓代嗤,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親缠借。 傳聞我的和親對(duì)象是個(gè)殘疾皇子干毅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容