Collection —— Set集合
第二部分(Set)
Set接口 ———— 繼承Collection
1、Set集合(是一個不可有重復元素的Collection)
1)Set集合的特點:是無序的(存儲和取出不一致),集合中的元素不可以重復
2)Set子實現類的特點
HashSet
它不保證 set 的叠代順序,特別是它不保證該順序恒久不變且元素不可以重復
LinkedHashSet(HashSet的子類)
底層數據結構是由哈希表和鏈表實現,所以它是有序的且元素不可以重復
TreeSet
底層數據結構是一種紅黑樹數據結構,保證元素的唯一性並且排序
2、HashSet類
1)概述:此類實現 Set 接口,由哈希表(實際上是一個 HashMap 實例)支持
2)唯一性(不可重復性)
HashSet的add方法,底層依賴於HashMap的put(Key,Value)方法
首先判斷它們的hash(),底層是調用HashCode()方法
如果HashCode():哈西碼值一樣,
然後在比較他們的內容是否相同(equals()方法)
所以在使用時,為了保證Set的不可重復性,需要重寫所存儲元素的HashCode()和equals()方法。
3)此類允許使用 null 當做元素
4)LinkedHashSet類 ———— 繼承HashSet
具有可預知叠代順序的 Set 接口的哈希表和鏈接列表實現類
哈希表:保證元素的唯一性
鏈表:元素的存儲和取出一致(有序性)
3、TreeSet類
有兩種排序方式:
1)紅黑樹結構儲存和取出元素的特點————基於TreeMap
儲存:將第一個存儲的元素作為根節點,其後元素與其作比較,大了作為右孩子放右邊,小了作為左孩子放左邊
取出:前序遍歷,中序遍歷,後序遍歷,依次取每一個元素的值
2)第一種排序方式:自然排序
需要集合中存儲元素所在的類實現(implements)Comparable接口,重寫compareTo()方法;
在基本數據的包裝類中他們已經實現接口並重寫了compareTo()方法,所以可以直接使用;
String中重寫的compareTo()方法:(與紅黑樹結構的儲存一致)
public int compareTo(String anotherString):按字典順序將此 String 對象表示的字符序列與參數字符串所表示的字符序列進行比較。
如果按字典順序此 String 對象位於參數字符串之前,則比較結果為一個負整數。
如果按字典順序此 String 對象位於參數字符串之後,則比較結果為一個正整數。
如果這兩個字符串相等,則結果為 0;
egg:
import java.util.TreeSet;
//需求:請按照姓名的長度排序
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>();
ts.add(new Student("zhaoyun", "七進七出"));
ts.add(new Student("zhangfei", "當陽怒吼"));
ts.add(new Student("guanyu", "水淹七軍"));
ts.add(new Student("zhugeliang", "七擒孟獲"));
ts.add(new Student("luxun", "火燒連營"));
ts.add(new Student("liubei","白帝托孤"));
for(Student s : ts){
System.out.println(s.getName() + "-----" + s.getStory());
}
}
}
public class Student implements Comparable<Student>{
private String name;
private String story;
//有參無參構造器;
//get()set()方法;
@Override
public int compareTo(Student o) {
int num = this.getName().length() - o.getName().length(); //姓名短的放前面,長的放後面
int num2 = num == 0 ? this.getStory().compareTo(o.getStory()) : num; //如果姓名長度一樣,比較story是否一樣
return num2;
}
}
3)第二種排序方式:比較器排序
在創建TreeSet對象的時候,使用TreeSet(Comparator<? super E> comparator)構造方法傳入一個Comparator接口的子實現類對象,在子實現類中重寫int compare(T o1, T o2)方法;
可以通過創建一個Comparator的子實現類或者使用匿名內部類來完成(推薦使用匿名內部類)
compare(T o1,T o2)方法就相當於compareTo(T t)方法,返回負值就把o2放到o1的後頭,返回正值就把o2放01的前頭
egg:
import java.util.Comparator;
import java.util.TreeSet;
//根據字符串的長度排序,長的在前
public class TreeSetTest2 {
public static void main(String[] args) {
TreeSet<String> ts = new TreeSet<String>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int num = o2.length() - o1.length();
int num2 = num == 0 ? o1.compareTo(o2) : num;
return num2;
}
});
ts.add("aa");
ts.add("aaa");
ts.add("aab");
ts.add("aab");
ts.add("aabdf");
for(String s : ts){
System.out.println(s);
}
}
}
4、練習
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
/*
* 1:鍵盤錄入5個學生信息(姓名,語文成績,數學成績,英語成績),按照總分從高到低輸出到控制臺
*/
public class TreeSetDemo2 {
public static void main(String[] args) {
TreeSet<Students> ts = new TreeSet<Students>(new Comparator<Students>() {
@Override
public int compare(Students o1, Students o2) {
int sub1 = Integer.parseInt(o1.getChinese()) + Integer.parseInt(o1.getMath())
+ Integer.parseInt(o1.getEnglish());
int sub2 = Integer.parseInt(o2.getChinese()) + Integer.parseInt(o2.getMath())
+ Integer.parseInt(o2.getEnglish());
int num = sub2 - sub1;
int num2 = num == 0 ? o1.getName().compareTo(o1.getName()) : num;
return num2;
}
});
Scanner sc = new Scanner(System.in);
for(int i = 1;i <= 5;i++){
Students s = new Students();
System.out.println("請輸入第" + i + "個學生姓名:");
s.setName(sc.nextLine());
System.out.println("請輸入第" + i + "個學生的語文成績:");
s.setChinese(sc.nextLine());
System.out.println("請輸入第" + i + "個學生的數學成績:");
s.setMath(sc.nextLine());
System.out.println("請輸入第" + i + "個學生的英語成績:");
s.setEnglish(sc.nextLine());
ts.add(s);
}
for(Students s : ts){
System.out.println("學生姓名:" + s.getName() + "\t語文成績:" + s.getChinese()
+ "\t數學成績:" + s.getMath() + "\t英語成績:" + s.getEnglish()
+ "\t總分:" + (Integer.parseInt(s.getChinese()) + Integer.parseInt(s.getMath())
+ Integer.parseInt(s.getEnglish())));
}
}
}
public class Students {
private String name;
private String chinese;
private String math;
private String english;
//有參、無參構造器
//set()get()方法
}
Collection —— Set集合