1.4 Set集合:HashSet和TreeSet类
Set 集合
無序的,不能包含重復(fù)的對(duì)象
- Set 集合類似于一個(gè)罐子,程序可以依次把多個(gè)對(duì)象“丟進(jìn)”Set 集合,而 Set 集合通常不能記住元素的添加順序。
- 也就是說 Set 集合中的對(duì)象不按特定的方式排序,只是簡(jiǎn)單地把對(duì)象加入集合-------無序。
- Set 集合中不能包含重復(fù)的對(duì)象,并且最多只允許包含一個(gè) null 元素---------不能重復(fù)元素。
Set 實(shí)現(xiàn)了 Collection 接口,它主要有兩個(gè)常用的實(shí)現(xiàn)類:HashSet 類和 TreeSet類。
HashSet 類
HashSet 是 Set 接口的典型實(shí)現(xiàn),大多數(shù)時(shí)候使用 Set 集合時(shí)就是使用這個(gè)實(shí)現(xiàn)類。HashSet 是按照 Hash 算法來存儲(chǔ)集合中的元素。因此具有很好的存取和查找性能。
HashSet 具有以下特點(diǎn):
- 不能保證元素的排列順序,順序可能與添加順序不同,順序也有可能發(fā)生變化。
- HashSet 不是同步的,如果多個(gè)線程同時(shí)訪問或修改一個(gè) HashSet,則必須通過代碼來保證其同步。
- 集合元素值可以是 null。
當(dāng)向 HashSet 集合中存入一個(gè)元素時(shí),HashSet 會(huì)調(diào)用該對(duì)象的 hashCode() 方法來得到該對(duì)象的 hashCode值,然后根據(jù)該 hashCode 值決定該對(duì)象在 HashSet 中的存儲(chǔ)位置。如果有兩個(gè)元素通過 equals() 方法比較返回的結(jié)果為true,但它們的 hashCode 不相等,HashSet 將會(huì)把它們存儲(chǔ)在不同的位置,依然可以添加成功。也就是說,兩個(gè)對(duì)象的 hashCode 值相等且通過 equals() 方法比較返回結(jié)果為 true,則 HashSet 集合認(rèn)為兩個(gè)元素相等。
在 HashSet 類中實(shí)現(xiàn)了 Collection 接口中的所有方法。HashSet 類的常用構(gòu)造方法重載形式如下。
- HashSet():構(gòu)造一個(gè)新的空的 Set 集合。
- HashSet(Collection<? extends E>c):構(gòu)造一個(gè)包含指定 Collection 集合元素的新 Set集合。其中,“< >”中的 extends 表示 HashSet 的父類,即指明該 Set 集合中存放的集合元素類型。c表示其中的元素將被存放在此 Set 集合中。
下面的代碼演示了創(chuàng)建兩種不同形式的 HashSet 對(duì)象。
HashSet hs = new HashSet(); // 調(diào)用無參的構(gòu)造函數(shù)創(chuàng)建HashSet對(duì)象 HashSet<String> hss = new HashSet<String>(); // 創(chuàng)建泛型的 HashSet 集合對(duì)象例 1
編寫一個(gè) Java 程序,使用 HashSet 創(chuàng)建一個(gè) Set 集合,并向該集合中添加 4 套食物。具體實(shí)現(xiàn)代碼如下:
首先使用 HashSet 類的構(gòu)造方法創(chuàng)建了一個(gè) Set 集合,接著創(chuàng)建了 4 個(gè) String 類型的對(duì)象,并將這些對(duì)象存儲(chǔ)到 Set 集合中。使用 HashSet 類中的 iterator() 方法獲取一個(gè) Iterator 對(duì)象,并調(diào)用其 hasNext() 方法遍歷集合元素,再將使用 next() 方法讀取的元素強(qiáng)制轉(zhuǎn)換為 String 類型。最后調(diào)用 HashSet 類中的 size() 方法獲取集合元素個(gè)數(shù)。
運(yùn)行該程序,輸出的結(jié)果如下:
肥宅快樂店 漢堡 炸雞 薯片 雞肉卷 有4個(gè)吃的注意:在以上示例中,如果再向 CourseSet 集合中再添加一個(gè)名稱為“Java入門教程”的 String 對(duì)象,則輸出的結(jié)果與上述執(zhí)行結(jié)果相同。也就是說,如果向 Set 集合中添加兩個(gè)相同的元素,則后添加的會(huì)覆蓋前面添加的元素,即在 Set 集合中不會(huì)出現(xiàn)相同的元素。
TreeSet 類
TreeSet 類同時(shí)實(shí)現(xiàn)了 Set 接口和 SortedSet 接口。
SortedSet 接口是 Set 接口的子接口,可以實(shí)現(xiàn)對(duì)集合進(jìn)行自然排序,因此使用 TreeSet 類實(shí)現(xiàn)的 Set 接口默認(rèn)情況下是自然排序的,這里的自然排序指的是升序排序。
TreeSet 只能對(duì)實(shí)現(xiàn)了 Comparable 接口的類對(duì)象進(jìn)行排序,因?yàn)?Comparable 接口中有一個(gè)compareTo(Object o) 方法用于比較兩個(gè)對(duì)象的大小。例如 a.compareTo(b),如果 a 和 b相等,則該方法返回 0;如果 a 大于 b,則該方法返回大于 0 的值;如果 a 小于 b,則該方法返回小于 0 的值。
表 1 列舉了 JDK 類庫(kù)中實(shí)現(xiàn) Comparable 接口的類,以及這些類對(duì)象的比較方式。
表 1 實(shí)現(xiàn)Comparable接口類對(duì)象的比較方式:
| 包裝類(BigDecimal、Biglnteger、 Byte、Double、Float、Integer、Long 及 Short) | 按數(shù)字大小比較 |
| Character | 按字符的 Unicode 值的數(shù)字大小比較 |
| String | 按字符串中字符的 Unicode 值的數(shù)字大小比較 |
TreeSet 類除了實(shí)現(xiàn) Collection 接口的所有方法之外,還提供了如表 2 所示的方法。
表 2 TreeSet類的常用方法:
| E first() | 返回此集合中的第一個(gè)元素。其中,E 表示集合中元素的數(shù)據(jù)類型 |
| E last() | 返回此集合中的最后一個(gè)元素 |
| E poolFirst() | 獲取并移除此集合中的第一個(gè)元素 |
| E poolLast() | 獲取并移除此集合中的最后一個(gè)元素 |
| SortedSet<E> subSet(E fromElement,E toElement) | 返回一個(gè)新的集合,新集合包含原集合中 fromElement 對(duì)象與 toElement對(duì)象之間的所有對(duì)象。包含 fromElement 對(duì)象,不包含 toElement 對(duì)象 |
| SortedSet<E> headSet<E toElement〉 | 返回一個(gè)新的集合,新集合包含原集合中 toElement 對(duì)象之前的所有對(duì)象。不包含 toElement 對(duì)象 |
| SortedSet<E> tailSet(E fromElement) | 返回一個(gè)新的集合,新集合包含原集合中 fromElement 對(duì)象之后的所有對(duì)象。包含 fromElement 對(duì)象 |
注意:表面上看起來這些方法很多,其實(shí)很簡(jiǎn)單。因?yàn)?TreeSet 中的元素是有序的,所以增加了訪問第一個(gè)、前一個(gè)、后一個(gè)、最后一個(gè)元素的方法,并提供了 3 個(gè)從 TreeSet 中截取子 TreeSet 的方法。
例1
import java.util.Iterator; import java.util.TreeSet;public class Test {public static void main(String[] args) {TreeSet<Integer> t=new TreeSet<Integer>();t.add(1);t.add(23);t.add(209);t.add(3);for(int i=0;i<t.toArray().length;i++){System.out.println(t.toArray()[i]);}} } 1 3 23 209例 2
本次有 5 名學(xué)生參加考試,當(dāng)老師錄入每名學(xué)生的成績(jī)后,程序?qū)凑諒牡偷礁叩呐帕许樞蝻@示學(xué)生成績(jī)。此外,老師可以查詢本次考試是否有滿分的學(xué)生存在,不及格的成績(jī)有哪些,90 分以上成績(jī)的學(xué)生有幾名。
下面使用 TreeSet 類來創(chuàng)建 Set 集合,完成學(xué)生成績(jī)查詢功能。具體的代碼如下:
import java.util.Iterator; import java.util.Scanner; import java.util.SortedSet; import java.util.TreeSet;public class Test {public static void main(String[] args) {TreeSet<Double> scores=new TreeSet<Double>();//創(chuàng)建TreeSet集合Scanner input=new Scanner(System.in);System.out.println("——學(xué)生成績(jī)管理系統(tǒng)——");for(int i=0;i<5;i++){System.out.println("第"+(i+1)+"個(gè)學(xué)生成績(jī)");double score=input.nextDouble();//將學(xué)生成績(jī)轉(zhuǎn)換為Double類型,添加到TreeSet集合中scores.add(Double.valueOf(score));}Iterator<Double> it=scores.iterator();//創(chuàng)建Iterator對(duì)象System.out.println("學(xué)生成績(jī)從低到高的排序?yàn)?#xff1a;");while(it.hasNext()){System.out.print(it.next()+" ");}System.out.println("\n請(qǐng)輸入要查詢的成績(jī):");double searchScore=input.nextDouble();//contains()方法用于判斷集合中包不包含某個(gè)元素,返回值是boolean。if(scores.contains(searchScore)){System.out.println("成績(jī)?yōu)?#34;+searchScore+"的學(xué)生存在");}else{System.out.println("成績(jī)?yōu)?#34;+searchScore+"的學(xué)生不存在");}//查詢不及格的學(xué)生成績(jī)SortedSet<Double> score1=scores.headSet(60.0);System.out.println("\n不及格的成績(jī)有:");for(int i=0;i<score1.toArray().length;i++){System.out.print(score1.toArray()[i]+"\t");}//查詢90分以上的學(xué)生成績(jī)SortedSet<Double> score2=scores.tailSet(90.0);System.out.println("\n90分以上的成績(jī)有");//toArray()的方法,把List轉(zhuǎn)化為數(shù)組for(int i=0;i<score2.toArray().length;i++){System.out.print(score2.toArray()[i]+"\t");}} }首先創(chuàng)建一個(gè) TreeSet 集合對(duì)象 scores,并向該集合中添加 5 個(gè) Double 對(duì)象。
接著使用 while 循環(huán)遍歷 scores 集合對(duì)象,輸出該對(duì)象中的元素,然后調(diào)用 TreeSet 類中的 contains() 方法獲取該集合中是否存在指定的元素。
最后分別調(diào)用 TreeSet 類中的 headSet() 方法和 tailSet() 方法獲取不及格的成績(jī)和 90 分以上的成績(jī)。
運(yùn)行該程序,執(zhí)行結(jié)果如下所示:
——學(xué)生成績(jī)管理系統(tǒng)—— 第1個(gè)學(xué)生成績(jī) 67 第2個(gè)學(xué)生成績(jī) 70 第3個(gè)學(xué)生成績(jī) 88 第4個(gè)學(xué)生成績(jī) 56 第5個(gè)學(xué)生成績(jī) 98 學(xué)生成績(jī)從低到高的排序?yàn)?#xff1a; 56.0 67.0 70.0 88.0 98.0 請(qǐng)輸入要查詢的成績(jī): 98 成績(jī)?yōu)?span id="ze8trgl8bvbq" class="token number">98.0的學(xué)生存在不及格的成績(jī)有: 56.0 90分以上的成績(jī)有 98.0注意:在使用自然排序時(shí)只能向 TreeSet 集合中添加相同數(shù)據(jù)類型的對(duì)象,否則會(huì)拋出 ClassCastException 異常。如果向 TreeSet 集合中添加了一個(gè) Double 類型的對(duì)象,則后面只能添加 Double 對(duì)象,不能再添加其他類型的對(duì)象,例如 String 對(duì)象等。
總結(jié)
以上是生活随笔為你收集整理的1.4 Set集合:HashSet和TreeSet类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1.3 List集合:ArrayList
- 下一篇: 1.5 Map集合:HashMap 和T