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