TreeSet存儲系統定義類型(引用、直接)
與 HashSet 不同的是,TreeSet 本身屬于排序的子類:
import java.util.TreeSet;
public class TreeSetDemo {
// 内部采用二叉樹有序存儲,此處的有序不是指按照存儲順序,而是指資料順序
public static void main(String[] args) {
TreeSet<String> treeSet = new TreeSet<>();
treeSet.add("B");
treeSet.add("C");
treeSet.add("A");
treeSet.add("D");
for(String s : treeSet){
System.out.println(s);
}
System.out.println((char)0);
}
}
// 會輸出ABCD
雖然在增加元素的時候屬于無序的操作,但是增加之後卻可以為使用者進行排序功能的實作。
對自定義類型進行排序
TreeSet 的集合因為借用了 Comparable 接口,同時可以去除重複值,而 HashSet 雖然是 Set 接口子類,但是對于沒有複寫 Object 的 equals 和 hashCode 方法的對象,加入了 HashSet 集合中也是不能去掉重複值的。
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
/**
* 關于 TreeSet 的排序實作,如果集合中對象是自定義的或者說其他系統定義的類沒有實作 Comparable 接口,
* 則不能實作 TreeSet 的排序,會報類型轉換(轉向 Comparable 接口)錯誤。 換句話說要添加到 TreeSet
* 集合中的對象的類型必須實作了 Comparable 接口。
* 不過 TreeSet 的集合因為借用了 Comparable 接口,同時可以去除重複值(compareTo(T[] o) ),而 HashSet
* 雖然是 Set 接口子類,但是對于沒有複寫 Object 的 equals 和 hashCode 方法的對象,加入了 HashSet 集合
* 中也是不能去掉重複值的。
*/
public class TreeSetDemo2 {
public static void main(String[] args) {
TreeSet<Person> treeSet = new TreeSet<>();
Person p1 = new Person("張三",20);
Person p2 = new Person("李四",19);
Person p3 = new Person("麻子",19);
treeSet.add(p1);
treeSet.add(p2);
treeSet.add(p3);
for(Person p : treeSet){
System.out.println(p);
}
System.out.println("-----分割線-----");
/** // 沒有重寫equals和hasCode方法時
* 之前使用 Comparable 完成的對于重複元素的判斷,那麼 Set 接口定義的時候本身就是不允許重複元素的,
* 那麼證明如果現在真的是有重複元素的話,使用 HashSet 也同樣可以進行區分。
* 此時發現,将下面代碼的equals和hashcode方法注釋掉可以發現,并沒有去掉所謂的重複元素,也就是說之前的操作并不是真正的重複元素的判斷,而是通過
* Comparable 接口間接完成的。
* 如果要想判斷兩個對象是否相等,則必須使用 Object 類中的 equals()方法。
* 從最正規的來講,如果要想判斷兩個對象是否相等,則有兩種方法可以完成: ·
* 第一種判斷兩個對象的編碼是否一緻,這個方法需要通過 hashCode()完成,即:每個對象有唯一的編碼
* 還需要進一步驗證對象中的每個屬性是否相等,需要通過 equals()完成。
* 是以此時需要覆寫 Object類中的 hashCode()方法,此方法表示一個唯一的編碼,一般是通過公式計算出來的。
*/
Set<Person> all = new HashSet<>();
all.add(new Person("張三", 10));
all.add(new Person("李四", 10));
all.add(new Person("李四", 10));
all.add(new Person("王五", 11));
System.out.println(all);
/**
* 重寫equals和hasCode後,可以發現重複元素不存在了,是以如果要想去掉重複元素需要依靠 hashCode()和
* equals()方法共同完成。
*/
}
/**
* Comparable<>後的泛型控制的是抽象方法compareTo裡面的參數類型,如果不給,方法自動建立Object參數
*/
static class Person implements Comparable<Person>{
private String name;
private int age;
@Override
public int compareTo(Person o) {
// this 與 o比較
// 傳回的資料:負數this小/零一樣大/正數this大
// 将比較的規則寫在這裡
if(this.age > o.age){
return 1;
}else if(this.age == o.age){
// 因為set集合不存儲重複元素,是以當判斷兩個元素相同時,并不會進行存儲第二個元素
return 0;
}else{
// return -1;
// 如果假設年齡相等的話,按字元串進行排序。
return this.name.compareTo(o.name);
}
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o){
return true;
}
if (o == null || getClass() != o.getClass()){
return false;
}
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
}