1. 程式人生 > >Collection —— Set集合

Collection —— Set集合

collection set hashset treeset linkedhashset

第二部分(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集合