Java集合Set的簡(jiǎn)單使用解析
Set的簡(jiǎn)單介紹
- Set接口是Collection的子接口,Set接口相較于Collection接口沒(méi)有提供額外的方法。
- Set 集合不允許包含相同的元素,如果試把兩個(gè)相同的元素加入同一個(gè) Set 集合中,則添加操作失敗。
- Set集合支持的遍歷方式和Collection集合一樣:foreach和Iterator。
- Set的常用實(shí)現(xiàn)類(lèi)有:HashSet、TreeSet、LinkedHashSet。
Set主要實(shí)現(xiàn)類(lèi):HashSet
HashSet概述
- HashSet 是 Set 接口的主要實(shí)現(xiàn)類(lèi),大多數(shù)時(shí)候使用 Set 集合時(shí)都使用這個(gè)實(shí)現(xiàn)類(lèi)。
- HashSet 按 Hash 算法來(lái)存儲(chǔ)集合中的元素,因此具有很好的存儲(chǔ)、查找、刪除性能。
- HashSet 具有以下特點(diǎn):
- 不能保證元素的排列順序
- HashSet 不是線(xiàn)程安全的
- 集合元素可以是 null
- HashSet 集合判斷兩個(gè)元素相等的標(biāo)準(zhǔn):兩個(gè)對(duì)象通過(guò) hashCode() 方法得到的哈希值相等,并且兩個(gè)對(duì)象的 equals() 方法返回值為true。
- 對(duì)于存放在Set容器中的對(duì)象,對(duì)應(yīng)的類(lèi)一定要重寫(xiě)hashCode()和equals(Object obj)方法,以實(shí)現(xiàn)對(duì)象相等規(guī)則。即:“相等的對(duì)象必須具有相等的hash散列碼”。
- HashSet集合中元素的無(wú)序性,不等同于隨機(jī)性。這里的無(wú)序性與元素的添加位置有關(guān)。具體來(lái)說(shuō):我們?cè)谔砑用恳粋€(gè)元素到數(shù)組中時(shí),具體的存儲(chǔ)位置是由元素的hashCode()調(diào)用后返回的hash值決定的。導(dǎo)致在數(shù)組中每個(gè)元素不是依次緊密存放的,表現(xiàn)出一定的無(wú)序性。
HashSet中添加元素的過(guò)程
第1步:當(dāng)向 HashSet 集合中存入一個(gè)元素時(shí),HashSet 會(huì)調(diào)用該對(duì)象的 hashCode() 方法得到該對(duì)象的 hashCode值,然后根據(jù) hashCode值,通過(guò)某個(gè)散列函數(shù)決定該對(duì)象在 HashSet 底層數(shù)組中的存儲(chǔ)位置。
第2步:如果要在數(shù)組中存儲(chǔ)的位置上沒(méi)有元素,則直接添加成功。
第3步:如果要在數(shù)組中存儲(chǔ)的位置上有元素,則繼續(xù)比較:
- 如果兩個(gè)元素的hashCode值不相等,則添加成功;(hashCode值不相等,兩個(gè)元素必不相同)
- 如果兩個(gè)元素的hashCode()值相等,則會(huì)繼續(xù)調(diào)用equals()方法:
- 如果equals()方法結(jié)果為false,則添加成功。
- 如果equals()方法結(jié)果為true,則添加失敗。
第2步添加成功,元素會(huì)保存在底層數(shù)組中。
第3步兩種添加成功的操作,由于該底層數(shù)組的位置已經(jīng)有元素了,則會(huì)通過(guò)鏈表的方式繼續(xù)鏈接,存儲(chǔ)。
重寫(xiě) hashCode() 方法的基本原則
- 在程序運(yùn)行時(shí),同一個(gè)對(duì)象多次調(diào)用 hashCode() 方法應(yīng)該返回相同的值。
- 當(dāng)兩個(gè)對(duì)象的 equals() 方法比較返回 true 時(shí),這兩個(gè)對(duì)象的 hashCode() 方法的返回值也應(yīng)相等。
- 對(duì)象中用作 equals() 方法比較的 Field,都應(yīng)該用來(lái)計(jì)算 hashCode 值。
注意:如果兩個(gè)元素的 equals() 方法返回 true,但它們的 hashCode() 返回值不相等,hashSet 將會(huì)把它們存儲(chǔ)在不同的位置,但依然可以添加成功。(這是經(jīng)典的錯(cuò)誤,標(biāo)準(zhǔn)的零分)
重寫(xiě)equals()方法的基本原則
重寫(xiě)equals方法的時(shí)候一般都需要同時(shí)復(fù)寫(xiě)hashCode方法。通常參與計(jì)算hashCode的對(duì)象的屬性也應(yīng)該參與到equals()中進(jìn)行計(jì)算。
推薦:開(kāi)發(fā)中直接調(diào)用Eclipse/IDEA里的快捷鍵自動(dòng)重寫(xiě)equals()和hashCode()方法即可。
Set實(shí)現(xiàn)類(lèi)之二:LinkedHashSet
LinkedHashSet 是 HashSet 的子類(lèi),不允許集合元素重復(fù)。
LinkedHashSet 根據(jù)元素的 hashCode 值來(lái)決定元素的存儲(chǔ)位置,但它同時(shí)使用雙向鏈表維護(hù)元素的次序,這使得元素看起來(lái)是以添加順序保存的。
LinkedHashSet插入性能略低于 HashSet,但在迭代訪問(wèn) Set 里的全部元素時(shí)有很好的性能。
Set實(shí)現(xiàn)類(lèi)之三:TreeSet
- TreeSet 是 SortedSet 接口的實(shí)現(xiàn)類(lèi),TreeSet 可以按照添加的元素的指定的屬性的大小順序進(jìn)行遍歷。
- TreeSet底層使用紅黑樹(shù)結(jié)構(gòu)存儲(chǔ)數(shù)據(jù)
新增的方法如下: (了解)
- Comparator comparator()
- Object first()
- Object last()
- Object lower(Object e)
- Object higher(Object e)
- SortedSet subSet(fromElement, toElement)
- SortedSet headSet(toElement)
- SortedSet tailSet(fromElement)
TreeSet特點(diǎn):不允許重復(fù)、實(shí)現(xiàn)排序(自然排序或定制排序)
- TreeSet 兩種排序方法:自然排序和定制排序。默認(rèn)情況下,TreeSet 采用自然排序。
自然排序:TreeSet 會(huì)調(diào)用集合元素的 compareTo(Object obj) 方法來(lái)比較元素之間的大小關(guān)系,然后將集合元素按升序(默認(rèn)情況)排列。
如果試圖把一個(gè)對(duì)象添加到 TreeSet 時(shí),則該對(duì)象的類(lèi)必須實(shí)現(xiàn) Comparable 接口。
實(shí)現(xiàn) Comparable 的類(lèi)必須實(shí)現(xiàn) compareTo(Object obj) 方法,兩個(gè)對(duì)象即通過(guò) compareTo(Object obj) 方法的返回值來(lái)比較大小。
定制排序:如果元素所屬的類(lèi)沒(méi)有實(shí)現(xiàn)Comparable接口,或不希望按照升序(默認(rèn)情況)的方式排列元素或希望按照其它屬性大小進(jìn)行排序,則考慮使用定制排序。定制排序,通過(guò)Comparator接口來(lái)實(shí)現(xiàn)。需要重寫(xiě)compare(T o1,T o2)方法。
利用int compare(T o1,T o2)方法,比較o1和o2的大小:如果方法返回正整數(shù),則表示o1大于o2;如果返回0,表示相等;返回負(fù)整數(shù),表示o1小于o2。
要實(shí)現(xiàn)定制排序,需要將實(shí)現(xiàn)Comparator接口的實(shí)例作為形參傳遞給TreeSet的構(gòu)造器。
因?yàn)橹挥邢嗤?lèi)的兩個(gè)實(shí)例才會(huì)比較大小,所以向 TreeSet 中添加的應(yīng)該是同一個(gè)類(lèi)的對(duì)象。
對(duì)于 TreeSet 集合而言,它判斷兩個(gè)對(duì)象是否相等的唯一標(biāo)準(zhǔn)是:兩個(gè)對(duì)象通過(guò) compareTo(Object obj) 或compare(Object o1,Object o2)方法比較返回值。返回值為0,則認(rèn)為兩個(gè)對(duì)象相等。
到此這篇關(guān)于Java集合Set的簡(jiǎn)單使用解析的文章就介紹到這了,更多相關(guān)Set的簡(jiǎn)單使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JAVA 創(chuàng)建線(xiàn)程池的注意事項(xiàng)
這篇文章主要介紹了JAVA 創(chuàng)建線(xiàn)程池的注意事項(xiàng),文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07Java下3中XML解析 DOM方式、SAX方式和StAX方式
目前我知道的JAVA解析XML的方式有:DOM, SAX, StAX;如果選用這幾種,感覺(jué)還是有點(diǎn)麻煩;如果使用:JAXB(Java Architecture for XML Binding),個(gè)人覺(jué)得太方便了2013-04-04Eclipse中如何引入JUnit進(jìn)行單元測(cè)試
這篇文章主要介紹了Eclipse中如何引入JUnit進(jìn)行單元測(cè)試問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04Spring @Primary和@Qualifier注解原理解析
這篇文章主要介紹了Spring @Primary和@Qualifier注解原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04Java實(shí)現(xiàn)幾種常見(jiàn)排序算法代碼
排序(Sorting) 是計(jì)算機(jī)程序設(shè)計(jì)中的一種重要操作,它的功能是將一個(gè)數(shù)據(jù)元素(或記錄)的任意序列,重新排列成一個(gè)關(guān)鍵字有序的序列2013-09-09springboot實(shí)現(xiàn)公眾號(hào)接收回復(fù)消息和超過(guò)5秒被動(dòng)回復(fù)消息
本文主要介紹了springboot實(shí)現(xiàn)公眾號(hào)接收回復(fù)消息和超過(guò)5秒被動(dòng)回復(fù)消息,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05