Set集合

一. ArrayList嵌套

1.定義

在集合中存放集合,和二維數(shù)組類(lèi)似

2.演示

public static void main(String[] args) {

? ? //集合中的元素還是集合

? ? ArrayList<ArrayList<Student>> school = new ArrayList<>();

? ? ArrayList<Student> clas1 = new ArrayList<>();

? ? clas1.add(new Student("小紅",18));

? ? clas1.add(new Student("小明",20));

? ? school.add(clas1);

? ? ArrayList<Student> clas2 = new ArrayList<>();

? ? clas2.add(new Student("小張",18));

? ? clas2.add(new Student("小李",20));

? ? school.add(clas2);

? ? ArrayList<Student> clas3 = new ArrayList<>();

? ? clas3.add(new Student("tom",18));

? ? clas3.add(new Student("jack",20));

? ? school.add(clas3);


? ? System.out.println(school);

}



二. Set集合

1.定義

Set詞義:數(shù)學(xué)中集合的概念。也是Collection的子接口。

Set作為Collection集合的子接口猾普,沒(méi)有新增的功能次舌。但是有自己的存儲(chǔ)特點(diǎn)。

Set集合存數(shù)的元素是無(wú)序的, 而且不允許儲(chǔ)存重復(fù)的元素, 每當(dāng)有新的元素存入的時(shí)候,Set集合會(huì)先去過(guò)濾, 如果發(fā)現(xiàn)和集合中現(xiàn)有元素出現(xiàn)重復(fù),不在允許添加

2.應(yīng)用場(chǎng)景

當(dāng)我們不想讓集合中出現(xiàn)重復(fù)的元素時(shí),使用Set集合

當(dāng)我們需要排除重復(fù)數(shù)據(jù)時(shí),使用Set集合

3.演示

public static void main(String[] args) {

? ? //集合中的元素還是集合

? ? HashSet<Student> s = new HashSet<>();

? ? Student student = new Student("小紅",18);

? ? Student student2 = new Student("小紅",18);

? ? s.add(student);

? ? s.add(student2);

? ? Iterator<Student> it = s.iterator();

? ? while(it.hasNext()) {

? ? ? ? Student student3=it.next();

? ? ? ? System.out.println(student3);

? ? }

}


三. HashSet

1.定義

Set接口的一個(gè)具體的實(shí)現(xiàn)類(lèi)约素。

底層是由哈希表實(shí)現(xiàn)。它不保證迭代的順序。特別是不保證順序一直不變硅急。

HashSet集合中的元素是通過(guò)hash值來(lái)比較是否相同

集合通過(guò)元素的hashCodeequals方法來(lái)比較兩個(gè)元素是否相同, 不同就存入, 相同不存入

元素存入的位置未知,和存入的順序無(wú)關(guān)

2.存儲(chǔ)原理

HashSet最后還是存入數(shù)組中, 只是根據(jù)元素的Hash值來(lái)確定存入的角標(biāo)位置

元素的hash值 ^ (元素的hash值 >>> 16) & (數(shù)組的長(zhǎng)度-1)

HashSet中不是直接存入我們給定的元素, 而是用集合中的一個(gè)內(nèi)部類(lèi)封裝我們存入的元素,所以當(dāng)我們存入null的時(shí)候,不會(huì)因?yàn)楹蛿?shù)組中角標(biāo)位上默認(rèn)值null起沖突

如果兩個(gè)不同的元素根據(jù)不同的Hash值計(jì)算出了同一個(gè)角標(biāo)值,那么都能存進(jìn)去

3.構(gòu)造方法

HashSet()? ? 構(gòu)造出一個(gè)新的集合, 底層數(shù)組默認(rèn)的初始容量是16(擴(kuò)容一倍),加載因子是0.75

加載因子: 集合中的數(shù)組可用的

角標(biāo)值得可選范圍越小,計(jì)算出重復(fù)角標(biāo)值得概率就越高

HashSet(Collection<? extends E> c) 構(gòu)造一個(gè)包含指定collection中元素的新set?

4.常用方法

boolean add( E e)? ? 如果此set集合中尚未包含指定元素,則添加指定元素

boolean remove(Object o)? ? 移除某個(gè)元素 []

int size()? ? 獲取集合的長(zhǎng)度

5.重點(diǎn)重點(diǎn)重點(diǎn)!<阉臁营袜!HashSet集合去重的流程

step1:先獲取對(duì)象的hashCode,對(duì)象的哈希值不同丑罪,直接存儲(chǔ)到HashSet容器中荚板。

step2:如果哈希值相同調(diào)用equals()比較吩屹。

true:認(rèn)為是相同的元素跪另,不存儲(chǔ)

false:不同的元素,存儲(chǔ)

原則:hashCode()和equals()的原則:

重寫(xiě)hashCode()的規(guī)則:自己生成hashCode值煤搜。公式

對(duì)象相同:屬性值相同免绿。那么哈希碼必須相同。

對(duì)象不同:屬性值不同擦盾。哈希碼也可能相同嘲驾。

重寫(xiě)equals()的原則:"權(quán)威的"

如果兩個(gè)對(duì)象的屬性值相同淌哟,認(rèn)為是相同的對(duì)象,返回true辽故。

如果兩個(gè)對(duì)象的屬性值有不同徒仓,就不是相同的對(duì)象,返回false誊垢。

結(jié)論:如果想使用HashSet集合掉弛,那么必須同時(shí)重寫(xiě)對(duì)象的hashCode()和equals()這兩個(gè)方法。


重寫(xiě)的規(guī)則:

hashCode()

對(duì)象相同彤枢,屬性值相同狰晚。哈希碼必須相同。

對(duì)象不同缴啡,屬性值不同壁晒。哈希碼可能相同。

equals()

對(duì)象相同:屬性值相同业栅。必須true秒咐。

對(duì)象不同:屬性值不同。必須false碘裕。

6.演示

需求: 去除ArrayList集合中的重復(fù)元素

public static void main(String[] args) {

? ? ArrayList<String> al = new ArrayList<>();

? ? al.add("a");

? ? al.add("s");

? ? al.add("x");

? ? al.add("a");

? ? al.add("s");

? ? HashSet<String> hs = new HashSet<>(al);

? ? System.out.println(hs);

}

7.測(cè)試題

需求: 創(chuàng)建Student類(lèi), 定義name和age屬性, 創(chuàng)建多個(gè)對(duì)象(有屬性重復(fù)的對(duì)象)存入ArrayList集合中, 然后對(duì)集合中的元素去重


四. HashSet集合中元素保證唯一性

1.原理解析

HashMap是通過(guò)調(diào)用元素的hashCode方法來(lái)比較兩個(gè)元素是否形同的,所有如果要保證引用數(shù)據(jù)類(lèi)型邏輯上的唯一性,就必須重寫(xiě)hashCode方法和equals方法

2.演示

public int hashCode() {

????final int prime = 31;

????int result = 1;

????result = prime * result + age;

????result = prime * result + ((name == null) ? 0 : name.hashCode());

????return result;

}

prime = 31 的原因

????別人選的, 沒(méi)有原因

????是質(zhì)數(shù), 和別的值計(jì)算得出的數(shù)重復(fù)的概率低

????大小適中, 不會(huì)出現(xiàn)太大導(dǎo)致結(jié)果無(wú)法使用的問(wèn)題

????便于計(jì)算 2<<5 -1

3.引用數(shù)據(jù)類(lèi)型除重

重寫(xiě)hashCode和equals方法,自定義比較內(nèi)容

4.測(cè)試題

需求: 編寫(xiě)程序, 獲取10個(gè)1到20的隨機(jī)數(shù), 要求隨機(jī)數(shù)不能重復(fù), 打印結(jié)果

public static void main(String[] args) {

????Random random = new Random();

????HashSet<Integer> hashSet = new HashSet<>();

????while(hashSet.size()<10){

????????int num = random.nextInt(20)+1;

????????hashSet.add(num);

????}

????System.out.println(hashSet);

}

5.測(cè)試題

需求: 從鍵盤(pán)錄入一行數(shù)據(jù), 去掉其中重復(fù)的字符,打印結(jié)果

6.測(cè)試題

產(chǎn)生10個(gè)隨機(jī)的字符串, 要求不能重復(fù)(字符串中的字符取值在 'a' 到 'z' , 'A' 到 'Z' ,'0' 到 '9'),字符串的長(zhǎng)度1-20


五. LinkedHashSet

1.定義

兼顧了linked的有序性和HashSet的元素唯一性

2.演示




六. TreeSet集合

1.定義

TreeSet是一種順序的集合, 記住, 這里的順序是指集合中的元素有順序, 她是通過(guò)比較元素的大小來(lái)存放的, 大的存右邊,小的存左邊

默認(rèn)的規(guī)則:Comparable接口携取,定義排序的規(guī)則。

存入的元素必須實(shí)現(xiàn)Comparable接口,并且重寫(xiě)comparTo方法(注:重寫(xiě)的方法應(yīng)在該元素的類(lèi)中帮孔,而不是測(cè)試類(lèi)中重寫(xiě)

java.lang.Comparable接口的用途:強(qiáng)行對(duì)實(shí)現(xiàn)類(lèi)的對(duì)象進(jìn)行排序雷滋。

compareTo()-->此方法用于排序,返回值int類(lèi)型

o1.compareTo(o2)-->int

????正數(shù):o1 > o2文兢,將o1排在o2的后面晤斩。

????負(fù)數(shù):o1 < o2,將o1排在o2的前面姆坚。

????零:認(rèn)為o1和o2相同澳泵,不存儲(chǔ)了。

最后存入的元素會(huì)形成一個(gè)樹(shù)狀結(jié)構(gòu)

擴(kuò)展內(nèi)容:

紅黑樹(shù)--->平衡二叉樹(shù)--->二叉樹(shù)--->樹(shù)

想了解平衡二叉樹(shù)兼呵,可以參照此網(wǎng)址:https://baijiahao.baidu.com/s?id=1651427207567199156&wfr=spider&for=pc

2.構(gòu)造方法

TreeSet()? ? 構(gòu)造一個(gè)新的空set, 該set根據(jù)其元素的自然順序進(jìn)行排序

TreeSet(Comparator <? super E> comparator)? 構(gòu)建一個(gè)空的TreeSet, 他根據(jù)指定比較器進(jìn)行排序

3.常用方法

add(E e)? ? 將指定元素添加到此set

first()? ? 返回此set中當(dāng)前第一元素

last()? ? 返回此set中當(dāng)前最后一個(gè)元素

floor()? ? 返回此set中小于等于給定元素的最大元素,不存在則返回null

higher()? ? 返回此set中嚴(yán)格大于給定元素的最小元素,不存在則返回null

5.添加原理

TreeSet會(huì)將第一個(gè)添加的元素作為中點(diǎn), 以后添加的元素會(huì)先跟中點(diǎn)進(jìn)行比較, 如果大于就接著跟所比較元素的右邊的元素接著比較,如果小于就接著跟所比較元素左邊的元素接著比較, 直到無(wú)法找到可比較的元素,就會(huì)將新添加的這個(gè)元素放到當(dāng)前位置

6.Comparable接口(默認(rèn)的比較器)

java.lang.Comparable接口

java.lang.Comparable接口的用途:強(qiáng)行對(duì)實(shí)現(xiàn)類(lèi)的對(duì)象進(jìn)行排序兔辅。

僅有唯一的一個(gè)方法:compareTo()-->此方法用于排序,返回值int類(lèi)型類(lèi)型

o1.compareTo(o2)-->int ?? (從小到大排序)

????正數(shù):o1 > o2击喂,將o1排在o2的后面维苔。

????負(fù)數(shù):o1 < o2,將o1排在o2的前面懂昂。

????零:認(rèn)為o1和o2相同蕉鸳,不存儲(chǔ)了。

默認(rèn)的TreeSet集合忍法,使用的是Comparable接口潮尝,來(lái)給對(duì)象進(jìn)行排序。以及去重饿序。

所有存入的元素在比較的時(shí)候,如果集合沒(méi)有比較器, 就會(huì)將元素本身轉(zhuǎn)成Comparator類(lèi)型并調(diào)用comparTo方法進(jìn)行比較, 所以我們必須實(shí)現(xiàn)Comparato接口,并重寫(xiě)comparTo方法

7.Comparator比較器(自定義的比較器)

這是一個(gè)接口, 定義了一個(gè)compare抽象方法

compare方法可以對(duì)兩個(gè)元素進(jìn)行比較

????如果方法返回一個(gè)小于0的數(shù),表示參數(shù)1小于參數(shù)2

????如果返回 0 ,表示參數(shù)1等于參數(shù)2

????如果返回一個(gè)大于0的數(shù), 表示參數(shù)1大于參數(shù)2

演示

8.注意事項(xiàng)

TreeSet集合的存儲(chǔ)原理限定了必須要對(duì)存入的元素進(jìn)行比較

要么存入的元素自身實(shí)現(xiàn)Comparable接口, 要么提供外部的實(shí)現(xiàn)了Comparator接口的比較器, 否則程序運(yùn)行就會(huì)報(bào)錯(cuò)


注意點(diǎn):創(chuàng)建一個(gè)TreeSet集合勉失,到底使用哪個(gè)比較器?Comparable乱凿?Comparator?

無(wú)參構(gòu)造:new TreeSet();-->使用默認(rèn)的比較器:Comparable

有參構(gòu)造:new TreeSet(Comparator)-->使用自定義的比較器:Comparator

9.測(cè)試題

需求: 鍵盤(pán)錄入5個(gè)學(xué)生信息(姓名,語(yǔ)文成績(jī),數(shù)學(xué)成績(jī),英語(yǔ)成績(jī)),按照總分從高到低輸出到控制臺(tái)

演示

10.LinkedHashSet集合

回憶:HashSet存儲(chǔ)特點(diǎn)咽弦?1徒蟆、無(wú)序。2型型、去重

HashSet存儲(chǔ)數(shù)據(jù)段审,記錄存儲(chǔ)的順序。

Set集合的另一個(gè)實(shí)現(xiàn)類(lèi):LinkedHashSet

存儲(chǔ)原理同HashSet相同闹蒜,但是外層套了一個(gè)鏈表結(jié)構(gòu)寺枉。用于記錄存儲(chǔ)的順序。

七. 超級(jí)for

1.定義

????Iterator的簡(jiǎn)寫(xiě)形式

????簡(jiǎn)化數(shù)組和Collection集合的遍歷

2.格式

3.演示

4.三種迭代方式的刪除

????普通for循環(huán),可以刪除,但是需要角標(biāo)

????迭代器,可以刪除,但是必須使用迭代器自身的remove方法,否則會(huì)出現(xiàn)并發(fā)修改異常

????超級(jí)for循環(huán)不能刪除


八. Collections工具類(lèi)的使用

1.定義

????一個(gè)用于操作Collection集合工具類(lèi)

2.常用方法

????sort(List<T> list) 根據(jù)元素的自然順序排序

????swap(List<T> list , int i , int j) 交換集合中兩個(gè)角標(biāo)位上的值

????reverse(List<?> list ) 反轉(zhuǎn)集合中的元素的順序

????replaceAll(List<T> list, T oldVal, T newVal) 替換

3.演示


總結(jié)

1.Set集合:特點(diǎn)绷落,去重姥闪,無(wú)序。

2.HashSet:

????去重效率高, 尤其是在大數(shù)據(jù)量下砌烁,散列存儲(chǔ)筐喳。不講究存儲(chǔ)順序。

????調(diào)用元素的hashCode和equals方法來(lái)比較是否相同

3.TreeSet:

? ? 去重, 元素有序(對(duì)存入的元素進(jìn)行排序)

????要求存入的元素必須具備比較的能力或者提供第三方的比較器

????元素具備比較的能力 : 元素實(shí)現(xiàn)comperable接口, 重寫(xiě)comparTo方法

????第三方比較器: 定義類(lèi),實(shí)現(xiàn)Compartor接口, 從寫(xiě)? compare方法

4.LinkedHashSet

????即有序(集合有序), 又能去重

????效率不高

5.超級(jí)for

????迭代器的簡(jiǎn)寫(xiě)形式

????優(yōu)點(diǎn): 格式簡(jiǎn)單

????缺點(diǎn): 無(wú)法進(jìn)行刪除操作

6.Collections

????一個(gè)用來(lái)操作List集合的工具類(lèi)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末函喉,一起剝皮案震驚了整個(gè)濱河市避归,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌函似,老刑警劉巖槐脏,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異撇寞,居然都是意外死亡顿天,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)蔑担,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)牌废,“玉大人,你說(shuō)我怎么就攤上這事啤握∧衤疲” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)懂从。 經(jīng)常有香客問(wèn)我授段,道長(zhǎng),這世上最難降的妖魔是什么番甩? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任侵贵,我火速辦了婚禮,結(jié)果婚禮上缘薛,老公的妹妹穿的比我還像新娘窍育。我一直安慰自己,他們只是感情好宴胧,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布漱抓。 她就那樣靜靜地躺著,像睡著了一般恕齐。 火紅的嫁衣襯著肌膚如雪乞娄。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 50,084評(píng)論 1 291
  • 那天檐迟,我揣著相機(jī)與錄音补胚,去河邊找鬼。 笑死追迟,一個(gè)胖子當(dāng)著我的面吹牛溶其,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播敦间,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼瓶逃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了廓块?” 一聲冷哼從身側(cè)響起厢绝,我...
    開(kāi)封第一講書(shū)人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎带猴,沒(méi)想到半個(gè)月后昔汉,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拴清,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年靶病,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片口予。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡娄周,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出沪停,到底是詐尸還是另有隱情煤辨,我是刑警寧澤裳涛,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站众辨,受9級(jí)特大地震影響端三,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜泻轰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一技肩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浮声,春花似錦、人聲如沸旋奢。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)至朗。三九已至屉符,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間锹引,已是汗流浹背矗钟。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嫌变,地道東北人吨艇。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像腾啥,于是被迫代替她去往敵國(guó)和親东涡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351