Java基礎(chǔ)day14筆記:集合框架|迭代器|ArrayList|LinkedList|Vector|HashSet

2019/7/1 二刷結(jié)束留念

mark:重寫(xiě)equals和hashCode方法的情景~


????01-集合框架(體系概述)

? ? ? ? 為什么會(huì)出現(xiàn)集合類(lèi)呢儿咱?? ? ? ??

? ? ? ? 面向?qū)ο笳Z(yǔ)言對(duì)事物的體現(xiàn)都是以對(duì)象的形式,所以為了方便對(duì)多個(gè)對(duì)象的操作牢撼,就對(duì)對(duì)象進(jìn)行存儲(chǔ),集合就是存儲(chǔ)對(duì)象最常用的一種方式满葛。

? ? ? ? 那存到哪里去捏?

? ? ? ? 有兩種存儲(chǔ)的地方可以用医男,第一種是數(shù)組滑绒,第二種是集合。

? ? ? ? 對(duì)象多了用集合存骚勘,數(shù)據(jù)多了用對(duì)象存铐伴,像姓名年齡這些都是數(shù)據(jù)~

? ? ? ? 可是已經(jīng)有數(shù)組啦,為什么還要有集合呢调鲸?

? ? ? ? 數(shù)組是固定長(zhǎng)度的盛杰,集合是可變長(zhǎng)度的。

? ? ? ? 而且藐石,數(shù)組當(dāng)中存儲(chǔ)對(duì)象的時(shí)候即供,它只能存儲(chǔ)同一種類(lèi)型的對(duì)象,比如說(shuō)全存Demo或者全存Person于微,因?yàn)閿?shù)組定義的時(shí)候已經(jīng)指定了數(shù)據(jù)類(lèi)型啦逗嫡。

? ? ? ? 而集合不是,對(duì)它來(lái)說(shuō)只要是對(duì)象就行株依。先存一個(gè)new Person()進(jìn)去驱证,再存一個(gè)new Demo()進(jìn)去,都沒(méi)問(wèn)題噠恋腕。

? ? ? ? 所以抹锄,集合的特點(diǎn)是:集合的長(zhǎng)度是可變的,集合可以存儲(chǔ)不同類(lèi)型的對(duì)象。

? ? ? ? 集合作為一種容器伙单,也劃分成了很多種获高。對(duì)它們不斷的進(jìn)行共性抽取,就形成了一個(gè)體系吻育,我們叫做集合框架念秧。

? ? ? ? 嘿嘿,這個(gè)圖看著理解一下:

? ? ? ? 這個(gè)體系里面包含很多內(nèi)容布疼。

? ? ? ? 框架產(chǎn)生之后摊趾,我們一般會(huì)先看什么呢?

? ? ? ? 是不是會(huì)先看頂層呀~因?yàn)轫攲赢?dāng)中定義的是這個(gè)體系當(dāng)中最共性、最基本的行為游两,把這個(gè)頂層看明白之后砾层,這個(gè)體系的基本功能就了解了。

? ? ? ? 看完了頂層之后器罐,找底層來(lái)用~

? ? ? ? 為什么呢梢为?

? ? ? ? 有兩點(diǎn)原因:

? ? ? ? 1,不斷向上抽取出來(lái)的東西很有可能是不能創(chuàng)建對(duì)象的轰坊,它可能是抽象的铸董。

? ? ? ? 2,創(chuàng)建子類(lèi)對(duì)象肴沫,方法更多一些粟害。

? ? ? ? 所以說(shuō),參閱頂層颤芬,創(chuàng)建底層悲幅。

? ? ? ? 而這個(gè)頂層,就叫Collection站蝠,收集汰具、集合的意思。

? ? ? ? 集合框架是工具包中的一個(gè)成員菱魔,它在java.util這個(gè)包中留荔。

? ? ? ? Collection是一個(gè)接口。在不斷向上抽取的過(guò)程中澜倦,全變成抽象辣~它有很多實(shí)現(xiàn)類(lèi)聚蝶,也有很多子接口。

? ? ? ? 因?yàn)樽咏涌谔嘣逯危筒话€(gè)講啦碘勉。重點(diǎn)講兩個(gè):List和Set。

? ? ? ? 把剛剛那個(gè)示意圖簡(jiǎn)單填充了一下:

? ? ? ? 這些就是我們要重點(diǎn)講的內(nèi)容桩卵。

? ? ? ? 那么問(wèn)題來(lái)啦验靡,為什么要出現(xiàn)這么多種容器呢倍宾?

? ? ? ? 因?yàn)槊恳粋€(gè)容器對(duì)數(shù)據(jù)的存儲(chǔ)方式都有不同。

? ? ? ? 這個(gè)存儲(chǔ)方式稱(chēng)之為:數(shù)據(jù)結(jié)構(gòu)晴叨。

????02-集合框架(共性方法)

? ? ? ? 我們先從Collection開(kāi)始學(xué)起~

? ? ? ? Colletion是Colletion層次結(jié)構(gòu)中的跟接口凿宾。

????????方法摘要:

? ? ? ? 在上述方法中矾屯,我們發(fā)現(xiàn)了一些不清楚的數(shù)據(jù)類(lèi)型:

? ? ? ? 我們看到的這些不懂的字母兼蕊,就先把它們理解成Object類(lèi)~

? ? ? ? 頂層方法看完該建立子類(lèi)對(duì)象啦,我們先建立ArrayList對(duì)象吧~

? ? ? ? add方法的參數(shù)類(lèi)型是Object件蚕,以便于接收任意類(lèi)型對(duì)象孙技。

? ? ? ? 集合中存儲(chǔ)的都是對(duì)象的引用(地址)。就像這樣排作,簡(jiǎn)單示意圖:

? ? ? ? ?打印集合對(duì)象:

? ? ? ? 刪除元素:

????????運(yùn)行結(jié)果:

? ? ? ? 寫(xiě)這句就全刪啦(這個(gè)叫清空集合):

? ? ? ? 判斷元素:?

? ? ? ? 取交集:

? ? ? ? 取交集牵啦,al1中只會(huì)保留和al2中相同的元素~

? ? ? ? 再試試removeAll,是將和al2中相同的元素刪掉~(yú)

????03-集合框架(迭代器)

? ? ? ? 在Collection中妄痪,有一個(gè)方法叫iterator:

? ? ? ? 它是一個(gè)接口誒:

? ? ? ? 這個(gè)接口中有三個(gè)方法:

? ? ? ? 試著用一下:

? ? ? ? Iterator it=al.iterator();//獲取迭代器哈雏,用于取出集合中的元素。

????????我們發(fā)現(xiàn)它將集合中的前兩個(gè)元素拿出來(lái)啦衫生。

????????但是如果這個(gè)集合中元素很多裳瘪,這樣一個(gè)一個(gè)寫(xiě)就太麻煩了。

? ? ? ? 我們有更方便的方法呢:

? ? ? ? 那么什么是迭代器呢罪针?

? ? ? ? 其實(shí)就是集合的取出元素的方式彭羹。

? ? ? ? 對(duì)于取出這個(gè)動(dòng)作,一個(gè)函數(shù)不能完全描述泪酱,需要用多個(gè)功能來(lái)體現(xiàn)派殷,這種情況下,就需要將功能們封裝到一個(gè)對(duì)象中去墓阀。

? ? ? ? 畫(huà)個(gè)圖解釋一下迭代器的特點(diǎn)毡惜,這里有三種容器,每個(gè)容器中都有一個(gè)取出的對(duì)象:

? ? ? ? 而且斯撮,因?yàn)閿?shù)據(jù)結(jié)構(gòu)的不同经伙,每個(gè)取出對(duì)象中的實(shí)現(xiàn)方式也不一樣。

? ? ? ? 那么吮成,這個(gè)取出就需要被描述一下橱乱,怎么描述呢?

? ? ? ? 通過(guò)一個(gè)類(lèi)來(lái)完成粱甫,而這個(gè)類(lèi)泳叠,就定義在了集合的內(nèi)部。

? ? ? ? 為什么定義在集合內(nèi)部呢茶宵?

? ? ? ? 因?yàn)樵鼐驮诩蟽?nèi)部危纫,如果想要操作這些元素,是不是集合的內(nèi)部類(lèi)最方便啦。

? ? ? ? 一般取出分為兩步:1种蝶,判斷元素是否存在2契耿,若存在則取出。

? ? ? ? 根據(jù)容器數(shù)據(jù)結(jié)構(gòu)的不同螃征,每個(gè)容器判斷和取出的具體實(shí)現(xiàn)細(xì)節(jié)不一樣搪桂。但是它們都是有共性?xún)?nèi)容:判斷和取出,那么可以將共性抽取盯滚,形成一個(gè)接口踢械,這個(gè)接口就是Iterator:

? ? ? ? 這些內(nèi)部類(lèi)都符合一個(gè)規(guī)則,該規(guī)則就是Iterator魄藕。

? ? ? ? 如何獲取集合的取出對(duì)象呢内列?

? ? ? ? 通過(guò)一個(gè)對(duì)外提供的方法:iterator();

? ? ? ? 這個(gè)對(duì)外提供的方法就相當(dāng)于娃娃機(jī)外面的操縱桿背率,而夾子就相當(dāng)于迭代器话瞧,它是封裝在娃娃機(jī)里面的,可以取出娃娃寝姿,只對(duì)外暴露了操縱桿這個(gè)方法交排,可以讓人使用。不同的娃娃機(jī)会油,它們的夾子也不一樣个粱,有兩個(gè)鉤的,有五個(gè)鉤的翻翩,實(shí)現(xiàn)方法都不一樣都许,但它們都是夾子~

? ? ? ? 后面我們?cè)俣x新的容器,只要將它的取出方法實(shí)現(xiàn)Iterator接口就可以啦:

? ? ? ? 取出方式就這樣被統(tǒng)一啦嫂冻,再新加集合也不怕~

? ? ? ? 除了用while循環(huán)胶征,它也可以用for循環(huán)寫(xiě):

? ? ? ? 這兩種循環(huán)有什么不同呢?

? ? ? ? 推薦用for循環(huán)桨仿,因?yàn)閒or循環(huán)結(jié)束后睛低,it就釋放了,不再占用內(nèi)存空間服傍,而while循環(huán)的話(huà)則依然占用內(nèi)存空間钱雷。

????04-集合框架(List集合共性方法)

Collection

? ? ? ? |——List:元素是有序的,元素可以重復(fù)吹零,因?yàn)樵摷象w系有索引罩抗。

? ? ? ? |——Set:元素是無(wú)序,元素不可以重復(fù)灿椅,該集合當(dāng)中沒(méi)有索引套蒂。

????????我們先講List钞支。

? ? ? ? 我們?nèi)ist類(lèi)中看一看它的方法~共性方法就不說(shuō)啦,它的特有方法有:

? ? ? ? 在指定位置插入指定元素:

? ? ? ? 通過(guò)索引獲取元素:

? ? ? ? 獲取元素的索引:

? ? ? ? List集合特有的迭代器:

? ? ? ? 移除指定元素:

? ? ? ? 改變指定位置的元素:

? ? ? ? 獲取指定區(qū)間元素(包含頭不包含尾):

? ? ? ? 綜上操刀,凡是可以操作角標(biāo)的方法都是List體系特有的方法烁挟。

? ? ? ? 總結(jié)一下:

? ? ? ? 接下來(lái)挨個(gè)演示一遍。

? ? ? ? 在指定位置添加元素:

? ? ? ? 刪除指定位置的元素:

? ? ? ? 修改元素:

? ? ? ? 通過(guò)角標(biāo)獲取元素:

? ? ? ? 獲取所有元素:

? ? ? ? 如上骨坑,List集合有自己特殊的取值方式撼嗓,就是遍歷。

? ? ? ? 我們用迭代器也可以實(shí)現(xiàn)這個(gè)功能:

????05-集合框架(ListIterator)

? ? ? ? 通過(guò)indexOf獲取對(duì)象的位置卡啰、獲取指定區(qū)間的元素:? ? ? ? ?

? ? ? ? 接下來(lái)看一下列表迭代器listIterator静稻。

? ? ? ? 它和普通迭代器到底有什么不同呢?

? ? ? ? 看示例:?

? ? ? ? 程序運(yùn)行過(guò)程中掛掉了:

? ? ? ? 我們來(lái)看一下這個(gè)異常:

? ? ? ? 我們來(lái)分析一下:

? ? ? ? 所以就存在安全隱患啦匈辱。不能同時(shí)用多種方式操作同一種元素,否則可能會(huì)發(fā)生并發(fā)修改異常杀迹。

? ? ? ? 那該怎么解決呢亡脸?

? ? ? ? 要么全用集合的方法,要么全用迭代器的方法树酪。

? ? ? ? 全用迭代器的方法:

? ? ? ? java02不是被刪除了嗎浅碾?為什么籃框部分還被打印了呢?

? ? ? ? 因?yàn)殡m然這個(gè)元素的引用被移除了续语,可是在移除前它還被obj使用了垂谢,后面打印的是obj~

? ? ? ? 注意,剛剛用的都是迭代器的操作疮茄,做了判斷滥朱、取出和移除,迭代器只能做這三個(gè)動(dòng)作力试,添加和修改動(dòng)作它做不了徙邻,有局限性。

? ? ? ? 不要怕~

? ? ? ? 它也知道自己有局限性畸裳,所以安排了一個(gè)小弟:

? ? ? ? 列表迭代器ListIterator有指針缰犁,有角標(biāo),所以它的方法比它的爸爸Iterator多多啦:

? ? ? ? 增刪查改樣樣都可以呢怖糊。

? ? ? ? List集合特有的迭代器:ListIterator是Iterator的子接口帅容。

? ? ? ? 我們用一下~?

? ? ? ? 添加:

? ? ? ? 修改:

? ? ? ? 除了hasNext,它還有hasPrevious:

? ? ? ? 試一下~?

? ? ? ? 我們反向取一次:

? ? ? ? 實(shí)際開(kāi)發(fā)中逆向遍歷用的少一些伍伤,正向遍歷用的多一些并徘。

? ? ? ? ListIterator出現(xiàn)后,可以對(duì)集合進(jìn)行在遍歷過(guò)程中的增刪改查嚷缭。

????06-集合框架(List集合具體對(duì)象的特點(diǎn))

????????Colletion中List集合的共性方法說(shuō)完以后饮亏,介紹一下List集合中常見(jiàn)的三個(gè)子類(lèi)對(duì)象: ArrayList耍贾、LinkedList、Vetor路幸。

? ? ? ? 這三個(gè)子類(lèi)對(duì)象的出現(xiàn)荐开,是因?yàn)榈讓拥臄?shù)據(jù)結(jié)構(gòu)不一樣而出現(xiàn)的,那么它們的底層到底是什么樣的數(shù)據(jù)結(jié)構(gòu)呢简肴?換句話(huà)說(shuō)晃听,它們的底層到底是怎樣對(duì)數(shù)據(jù)進(jìn)行存儲(chǔ)的呢?

? ? ? ? ArrayList:底層的數(shù)據(jù)結(jié)構(gòu)使用的是數(shù)組結(jié)構(gòu)砰识。特點(diǎn):查詢(xún)速度快能扒。但是增刪稍慢(元素不多還好,多了之后慢得就比較明顯)辫狼。線(xiàn)程不同步初斑。

數(shù)組數(shù)據(jù)結(jié)構(gòu)

? ? ? ? LinkedList:底層使用的鏈表數(shù)據(jù)結(jié)構(gòu)。特點(diǎn):增刪速度很快膨处,查詢(xún)稍慢见秤。


鏈表數(shù)據(jù)結(jié)構(gòu)

? ? ? ? Vector:底層是數(shù)組數(shù)據(jù)結(jié)構(gòu)。線(xiàn)程同步真椿。(它1.0就出現(xiàn)了鹃答,那個(gè)時(shí)候還木有集合框架呢,而ArrayList是1.2出現(xiàn)的)被ArrayList替代了突硝。

? ? ? ? ArrayList和Vector中测摔,建議用ArrayList,因?yàn)樾矢呓馇。瑹o(wú)論增刪還是查詢(xún)锋八,Vector都稍慢。

? ? ? ? 那多線(xiàn)程怎么辦吶修噪?

? ? ? ? 可以自己加鎖~

? ? ? ? 那我自己加鎖不安全怎么辦呢查库?

? ? ? ? 就怕你不會(huì)加所以Java的集合框架中提供了另外一個(gè)功能,專(zhuān)門(mén)幫助小笨笨來(lái)加鎖的~

? ? ? ? 怎么加呢黄琼?“把你的不安全的給我樊销,我給你個(gè)安全的≡嗫睿”好霸道總裁围苫。。撤师。

? ? ? ? 還有一個(gè)小問(wèn)題~ArrayList和Vector都是數(shù)組數(shù)據(jù)結(jié)構(gòu)剂府,而數(shù)組數(shù)據(jù)結(jié)構(gòu)的特點(diǎn)是它的長(zhǎng)度是固定的,集合卻是可變長(zhǎng)度的剃盾,所以ArrayList和Vector是可變長(zhǎng)度的數(shù)組腺占。什么叫可變長(zhǎng)度的數(shù)組呢淤袜?

? ? ? ? ArrayList默認(rèn)的長(zhǎng)度是10:

? ? ? ? 當(dāng)長(zhǎng)度超過(guò)之后,它會(huì)new一個(gè)新的數(shù)組衰伯,長(zhǎng)度是多少呢铡羡?50%延長(zhǎng),變15意鲸。然后烦周,把原來(lái)數(shù)組中的元素copy到新數(shù)組中來(lái),再把新元素拼接到它們后面怎顾。

? ? ? ? 而Vector長(zhǎng)度也是10读慎,超過(guò)之后new的新數(shù)組是100%延長(zhǎng)。

? ? ? ? 兩者相比槐雾,ArrayList好一些夭委,因?yàn)樗瓤梢匝娱L(zhǎng)又可以節(jié)省空間。Vector就比較浪費(fèi)空間啦蚜退。

? ? ? ? 總的來(lái)說(shuō)Vector現(xiàn)在都不用了闰靴,像這張圖中都沒(méi)有Vector:

? ? ? ? 最常用的就是加粗的這四塊。

????07-集合框架(Vector中的枚舉)

? ? ? ? 接下來(lái)講一下Vector的特點(diǎn)钻注。(不能理解既然它都不用了還要講它的特點(diǎn)是為什么。配猫。幅恋。)

? ? ? ? Collection通用的方法:

? ? ? ? Vector特有的方法(一般帶Element的都是它的特有方法):

? ? ? ? 添加元素:

? ? ? ? 查找元素:

? ? ? ? 插入:

? ? ? ? 刪除:

? ? ? ? 還有其他的:

? ? ? ? 我們來(lái)看一下這個(gè)方法:

? ? ? ? 這是什么東西鴨,木有見(jiàn)過(guò)呢:

? ? ? ? 點(diǎn)進(jìn)去這個(gè)接口看一下(這個(gè)接口叫枚舉):

? ? ? ? 那這個(gè)接口都有什么方法呢:

? ? ? ? 話(huà)不多說(shuō)泵肄,先玩一下~

? ? ? ? 枚舉就是Vector特有的取出方式捆交。

? ? ? ? 發(fā)現(xiàn)枚舉和迭代器很像。

? ? ? ? 其實(shí)腐巢,枚舉和迭代是一樣的。

? ? ? ? 因?yàn)槊杜e的名稱(chēng)以及方法的名稱(chēng)都過(guò)長(zhǎng),所以被迭代器取代了岔乔,枚舉郁郁而終了永品。

? ? ? ? 但是IO當(dāng)中有一個(gè)對(duì)象用到了枚舉,因?yàn)槟莻€(gè)對(duì)象也是1.0粗現(xiàn)的胃惜,那個(gè)時(shí)候沒(méi)有迭代泞莉,只有枚舉。

? ? ? ? Vector和ArrayList的區(qū)別是什么船殉?

? ? ? ? Vector支持枚舉鲫趁,ArrayList沒(méi)有枚舉。

????08-集合框架(LinkedList)

? ? ? ? 我們來(lái)看一看LinkedList里面有什么特有方法~

? ? ? ? 試一下利虫,addFirst:

? ? ? ? 再一次挨厚,addLast和getFirst堡僻、getLast:

? ? ? ? removeFirst:

? ? ? ? get...()和remove...()方法的區(qū)別:get可以獲取元素但不刪除元素,remove獲取元素疫剃,但是元素被刪除钉疫。

? ? ? ? 想把里面元素全取出來(lái)~

? ? ? ? 正著取:

? ? ? ? 倒著然派辍:

? ? ? ? removeFirst方法會(huì)拋出異常:

? ? ? ? 到了后期陌选,LinkedList方法升級(jí)了,它里面加了一個(gè)新的方法蹄溉,pollFirst/Last:

? ? ? ? 如果列表為空它不再拋出異常咨油,而是返回null,這是1.6版本出現(xiàn)的柒爵,以后推薦用這個(gè)方法喔役电。

? ? ? ? 獲取但不移除元素的新方法:

? ? ? ? 插入元素的新方法:

? ? ? ? 它們替代了之前舊的方法。

????09-集合框架(LinkedList練習(xí))

? ? ? ? 練習(xí):使用LinkedList模擬一個(gè)堆椕拚停或者隊(duì)列數(shù)據(jù)結(jié)構(gòu)法瑟。

? ? ? ? 描述隊(duì)列:??

? ? ? ? 封裝好之后,我們就可以直接使用啦:

? ? ? ? 注意哦唁奢,像這樣的封裝很常見(jiàn)霎挟。

? ? ? ? 為什么要封裝呢?我們直接用LinkedList不就可以完成了嗎麻掸?

? ? ? ? 但是LinkedList只有自身的含義酥夭,叫做鏈表,我們想把它做成跟我們項(xiàng)目相關(guān)的一些容器脊奋,那么我們需要起一些特定的名稱(chēng)來(lái)用更方便一些熬北,這個(gè)時(shí)候我們就會(huì)將原有的集合封裝進(jìn)我們的描述當(dāng)中,并且對(duì)外提供一個(gè)自己更容易識(shí)別的方法名稱(chēng)诚隙。

? ? ? ? 好啦讶隐,存完之后該取啦:

????10-集合框架(ArrayList練習(xí))

? ? ? ? 練習(xí):去除ArrayList中的重復(fù)元素。

? ? ? ? 思路:創(chuàng)建一個(gè)新容器久又,將舊容器的東西一個(gè)個(gè)放進(jìn)去巫延,放的時(shí)候判斷它是否已存在在新容器~

? ? ? ? 代碼:?

? ? ? ? 接下來(lái)刪除重復(fù)的:

????11-集合框架(ArrayList練習(xí)2)

? ? ? ? 練習(xí):將自定義對(duì)象作為元素存儲(chǔ)到ArrayList集合總,并去除重復(fù)元素籽孙。

? ? ? ? ? ? ? ? ? ?比如:存人對(duì)象烈评。將同姓名同年齡,視為同一個(gè)人犯建,為重復(fù)元素讲冠。

? ? ? ? 思路:

? ? ? ? Person類(lèi):

? ? ? ? 主函數(shù)中:

? ? ? ? 可是為什么這樣寫(xiě)會(huì)出錯(cuò)呢?

? ? ? ? 因?yàn)樵谕萜骼锩娲鍼erson的時(shí)候适瓦,add的其實(shí)是Object竿开,al.add(Object obj)谱仪,因?yàn)橹挥兴芙邮杖我鈱?duì)象。把Person傳進(jìn)去否彩,其實(shí)相當(dāng)于Object obj=new Person("lisi01",30);疯攒,這時(shí)Person就被提升為Object了。而后面的it.next()往回返的時(shí)候列荔,返回的是Object敬尺,Object中并沒(méi)有g(shù)etName方法,多態(tài)編譯失敗贴浙。

? ? ? ? 應(yīng)該改成這樣:

? ? ? ? 兩句合一句:

? ? ? ? 下面一句話(huà)也改一下:

? ? ? ? 運(yùn)行:

? ? ? ? 搞定砂吞。

? ? ? ? 接下來(lái)去重。

? ? ? ? 將之前寫(xiě)好的singleElement方法直接拿過(guò)來(lái)用:

? ? ? ? 我們可以看到崎溃,contains方法中其實(shí)調(diào)用了equals方法:

? ? ? ? 而默認(rèn)的equals方法顯然不適用于判斷我們新建立的對(duì)象蜻直,所以我們要在Person類(lèi)中重寫(xiě)equals方法:

? ? ? ? 調(diào)用singleElement方法:

? ? ? ? 刪除成功:

? ? ? ?List集合判斷元素是否相同,依據(jù)的是元素的equals方法袁串。 (其他的集合肯定不一樣)

? ? ? ? 雖然主函數(shù)中沒(méi)有直接調(diào)用equals方法概而,但是因?yàn)閏ontains方法調(diào)用了equals方法,而singleElement方法又調(diào)用了contains方法囱修。

? ? ? ? 這個(gè)問(wèn)題搞明白之后赎瑰,我們還會(huì)明白一系列其他問(wèn)題。

? ? ? ? 先將重寫(xiě)的equals方法注釋掉破镰,我們現(xiàn)在刪除一下其中一個(gè)元素:

? ? ? ? 但運(yùn)行結(jié)果是false而且刪除失敗了:

? ? ? ? 為什么呢乡范?

? ? ? ? 因?yàn)橐獎(jiǎng)h除這個(gè)元素,就得現(xiàn)在容器中尋找這個(gè)元素啤咽。remove底層也調(diào)用了equals。而默認(rèn)的equals方法是對(duì)比對(duì)象是否是同一個(gè)渠脉,new的Person是新的對(duì)象宇整,地址值不相同,所以肯定會(huì)刪除失敗芋膘。

? ? ? ? 現(xiàn)在將重寫(xiě)后的equals方法去掉注釋?zhuān)?/b>再試一下:

? ? ? ? 成功啦鳞青。

????12-集合框架(HashSet)

? ? ? ? 講完了List,那么ArrayList和LinkedList該用哪一個(gè)呢为朋?

? ? ? ? 如果元素中涉及了頻繁的增刪操作臂拓,用LinkedList。

? ? ? ? 如果增刪操作不頻繁习寸,可以選擇用LinkList胶惰,也可以選擇用ArrayList。

? ? ? ? 如果涉及了增刪霞溪,同時(shí)又涉及了查詢(xún)孵滞,建議使用ArrayList中捆。因?yàn)槠鋵?shí)頻繁的增刪操作并不多見(jiàn),一般的情況下都是查詢(xún)比較多坊饶。所以ArrayList作為一個(gè)最常見(jiàn)泄伪、最大頻率使用的容器存在,當(dāng)實(shí)在不知道該用誰(shuí)匿级,就用ArrayList蟋滴。

? ? ? ? List派系講完啦,接下來(lái)講Set派系痘绎。

? ? ? ? |——Set:元素是無(wú)序(存入和取出的順序不一定一致)津函,元素不可以重復(fù)。(想重復(fù)找List简逮,不重復(fù)找Set)

????????????????|——HashSet:底層數(shù)據(jù)結(jié)構(gòu)是哈希表球散。

? ? ? ? ? ? ? ? |——TreeSet:

? ? ? ? 看一下Set接口的方法,發(fā)現(xiàn)Set集合的功能和Colletion是一致的散庶。Colletion的方法我們之前都講過(guò)啦蕉堰,所以就不重復(fù)講啦。

? ? ? ? 每個(gè)對(duì)象都有哈希值悲龟,那什么是哈希表呢?

? ? ? ? 示例:

? ? ? ? ?發(fā)現(xiàn)它們都有哈希值:

? ? ? ? 接下來(lái)講講什么是哈希表:

? ? ? ? 很簡(jiǎn)單屋讶,存放哈希值的表就叫哈希表。哈希表的順序和元素的存放順序無(wú)關(guān)须教,和哈希值的大小有關(guān)皿渗。而取元素的時(shí)候也是按哈希值來(lái)取。

? ? ? ? 那會(huì)不會(huì)有哈希值相同的情況呢轻腺?

? ? ? ? 若哈希值相同乐疆,會(huì)判斷哈希值所指的對(duì)象是否相同,若不同贬养,會(huì)在這個(gè)哈希值上再向下順延一個(gè)挤土,表中有兩個(gè)這個(gè)哈希值(不知道我理解的對(duì)不對(duì),如果相同误算,那該怎么找對(duì)應(yīng)的對(duì)象呢):

? ? ? ? 驗(yàn)證無(wú)序:

? ? ? ? 驗(yàn)證唯一性:

????13-集合框架(HashSet存儲(chǔ)自定義對(duì)象)

? ? ? ? 還和11中的例子一樣仰美,存儲(chǔ)Person到HashSet中。? ? ?

? ? ? ? 將那個(gè)例子中的代碼都復(fù)制了過(guò)來(lái)儿礼,主函數(shù)中這樣寫(xiě):? ?

? ? ? ? 我們?cè)僭囋嚧嫒胫貜?fù)的Person對(duì)象咖杂,發(fā)現(xiàn)成功了:

? ? ? ? 為什么即使重寫(xiě)了equals方法,還是會(huì)出現(xiàn)重復(fù)呢蚊夫?

? ? ? ? 因?yàn)楝F(xiàn)在往里面存的四個(gè)對(duì)象都是獨(dú)立的诉字,都有獨(dú)立的哈希值,都存入了哈希表。

? ? ? ? 而我們現(xiàn)在要做的奏窑,就是覆蓋Person的哈希值方法导披,建立Person對(duì)象自己的哈希值。

? ? ? ? 怎么建立哈希值呢埃唯?

? ? ? ? 你的判斷條件是什么撩匕,我就依據(jù)你的條件來(lái)建立哈希值。比如這里是按照姓名和年齡來(lái)判斷對(duì)象是否重復(fù)的墨叛,那我們就按照姓名和年齡來(lái)建立哈希值止毕。

? ? ? ? 代碼:

? ? ? ? 注意,只有當(dāng)哈希值相同時(shí)漠趁,才會(huì)調(diào)用equals方法對(duì)比內(nèi)容是否相同扁凛。

? ? ? ??|——Set:元素是無(wú)序(存入和取出的順序不一定一致),元素不可以重復(fù)闯传。(想重復(fù)找List谨朝,不重復(fù)找Set)

????????????????|——HashSet:底層數(shù)據(jù)結(jié)構(gòu)是哈希表。

? ? ? ? ? ? ? ? ? ? ? ? HashSet是如何保證元素唯一性的呢甥绿?

? ? ? ? ? ? ? ? ? ? ? ? 是通過(guò)元素的兩個(gè)方法字币,hashCode和equals來(lái)完成。

? ? ? ? ? ? ? ? ? ? ? ? 如果元素的HashCode值相同共缕,才會(huì)判斷equals是否為true洗出。

? ? ? ? ? ? ? ? ? ? ? ? 如果元素的hashcode值不同,不會(huì)調(diào)用equals图谷。

? ? ? ? ? ? ? ? |——TreeSet:

? ? ????所以注意翩活,在開(kāi)發(fā)中,只要描述的對(duì)象要往哈希集合中存時(shí)便贵,一般都會(huì)復(fù)寫(xiě)hashCode和equals菠镇。? ??

? ? ? ? 還有注意,為了保證哈希值的唯一性承璃,一般會(huì)給這里乘個(gè)數(shù)字(兩個(gè)對(duì)象萬(wàn)一兩部分加起來(lái)正好是同一個(gè)值就重復(fù)了):

????14-集合框架(HashSet判斷和刪除的依據(jù))

? ? ? ? 注意辟犀,HashSet對(duì)于判斷元素是否存在,以及刪除等操作绸硕,依賴(lài)的方法是元素的hashCode和equals方法,而且先依賴(lài)hashCode魂毁,再依賴(lài)equals玻佩。

? ? ? ? ArrayList判斷元素是否存在,以及刪除等操作席楚,只依賴(lài)equals咬崔。

? ? ? ? 這個(gè)原因全都在數(shù)據(jù)結(jié)構(gòu)上,數(shù)據(jù)結(jié)構(gòu)不同,它依賴(lài)的方法也不一樣垮斯。? ??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末郎仆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子兜蠕,更是在濱河造成了極大的恐慌扰肌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件熊杨,死亡現(xiàn)場(chǎng)離奇詭異曙旭,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)晶府,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)桂躏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人川陆,你說(shuō)我怎么就攤上這事剂习。” “怎么了较沪?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵鳞绕,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我购对,道長(zhǎng)猾昆,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任骡苞,我火速辦了婚禮垂蜗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘解幽。我一直安慰自己贴见,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布躲株。 她就那樣靜靜地躺著片部,像睡著了一般。 火紅的嫁衣襯著肌膚如雪霜定。 梳的紋絲不亂的頭發(fā)上档悠,一...
    開(kāi)封第一講書(shū)人閱讀 49,046評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音望浩,去河邊找鬼辖所。 笑死,一個(gè)胖子當(dāng)著我的面吹牛磨德,可吹牛的內(nèi)容都是我干的缘回。 我是一名探鬼主播吆视,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼酥宴!你這毒婦竟也來(lái)了啦吧?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤拙寡,失蹤者是張志新(化名)和其女友劉穎授滓,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體倒庵,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡褒墨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了擎宝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片郁妈。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖绍申,靈堂內(nèi)的尸體忽然破棺而出噩咪,到底是詐尸還是另有隱情,我是刑警寧澤极阅,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布胃碾,位于F島的核電站,受9級(jí)特大地震影響筋搏,放射性物質(zhì)發(fā)生泄漏仆百。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一奔脐、第九天 我趴在偏房一處隱蔽的房頂上張望俄周。 院中可真熱鬧,春花似錦髓迎、人聲如沸峦朗。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)波势。三九已至,卻和暖如春橄维,著一層夾襖步出監(jiān)牢的瞬間尺铣,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工争舞, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留迄埃,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓兑障,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子流译,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

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