TreeSet集合如何保證元素唯一


TreeSet:

  1.特點

            TreeSet是用來排序的, 可以指定一個順序, 對象存入之后會按照指定的順序排列

  2.使用方式

     a.自然順序(Comparable)

           TreeSet類的add()方法中會把存入的對象提升為Comparable類型

           調用對象的compareTo()方法和集合中的對象比較(當前存入的是誰,誰就會調用compareTo方法)

           根據compareTo()方法返回的結果進行存儲

   b.比較器順序(Comparator)

          創建TreeSet的時候可以制定 一個Comparator

          如果傳入了Comparator的子類對象, 那么TreeSet就會按照比較器中的順序排序

          add()方法內部會自動調用Comparator接口中compare()方法排序

          調用的對象(就是當前存入的對象)是compare方法的第一個參數,集合中的對象(已經添加進去的對象)是compare方法的第二個參數

   c.兩種方式的區別

           TreeSet構造函數什么都不傳, 默認按照類中Comparable的順序(沒有就報錯ClassCastException)

           TreeSet如果傳入Comparator, 就優先按照Comparator

1. TreeSet存儲Integer類型的元素

package online.msym.set;
import java.util.Comparator;
import java.util.TreeSet;
import online.msym.bean.Person;
public class Demo3_TreeSet {
    /**
     * @param args
     * TreeSet集合是用來對象元素進行排序的,同樣他也可以保證元素的唯一    
     */
    public static void main(String[] args) {
        demo1();        
    }
    public static void demo1() {
        TreeSet<Integer> ts = new TreeSet<>();
        ts.add(3);
        ts.add(1);
        ts.add(1);
        ts.add(2);
        ts.add(2);
        ts.add(3);
        ts.add(3);        
        System.out.println("TreeSet存儲Integer類型的元素: " + ts);
    }
}

TreeSet1

2. TreeSet存儲自定義對象

package online.msym.set;
import java.util.Comparator;
import java.util.TreeSet;
import online.msym.bean.Person;
public class Demo3_TreeSet {
    /**
     * @param args
     * TreeSet集合是用來對象元素進行排序的,同樣他也可以保證元素的唯一
     * 當compareTo方法返回0的時候集合中只有一個元素
     * 當compareTo方法返回正數的時候集合會怎么存就怎么取
     * 當compareTo方法返回負數的時候集合會倒序存儲
     */
    public static void main(String[] args) {        
        demo2();        
    }
    public static void demo2() {
        //因為TreeSet要對元素進行排序,那你排序的依據是什么,姓名還是年齡還是其它的,得告訴它,怎么告訴?
        //需要讓Person類實現Comparable接口重寫compareTo方法
        TreeSet<Person> ts = new TreeSet<>();
        ts.add(new Person("張三", 23));
        ts.add(new Person("李四", 13));
        ts.add(new Person("周七", 13));
        ts.add(new Person("王五", 43));
        ts.add(new Person("趙六", 33));
        
        System.out.println(ts);
    }
    
}

TreeSet2

注意上面的輸出,跟添加的順序相反,那是因為compareTo方法的返回值

Person實體類:

package online.msym.bean;
//為了簡化代碼,這里沒有hashCode和equals方法,用的話可以直接將上面的Person類中的hashCode和equals復制過來
public class Person implements Comparable<Person> {
    private String name;
    private int age;
    public Person() {
        super();
        
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    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;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]\n";
    }        
    public int compareTo(Person o) {
        //return 0;
        //return 1;
        return -1
    }
    
}

TreeSet保證元素唯一和自然排序的原理和圖解

 

TreeSet保證元素唯一和自然排序的原理和圖解,小的放左側,大的放右側

1

2

 

按照Person類的年齡排序的話,Person類改寫為:

//注意使用此類時要生成空參有參構造,set和get方法,hashCode和equals方法
package online.msym.bean;
public class Person implements Comparable<Person> {
    private String name;
    private int age;    
    @Override
    //按照年齡排序
    public int compareTo(Person o) {
       int num = this.age - o.age; //按照年齡比較 
return num;
     //return num == 0 ? this.name.compareTo(o.name) : num;//姓名是比較的次要條件
    }    
}

TreeSet保證元素唯一和比較器排序的原理:

定義比較器是實現Comparator接口,重寫compare方法和equals方法,但是由於所有的類默認繼承Object,而Object中有equals方法,

所以自定義比較器類時,不用重寫equals方法,只需要重寫compare方法

字符串長度比較器圖解:

comparetor1

下面采用了兩種方式:匿名的內部類的比較器對象,自定義的比較器對象,

package online.msym.test;
import java.util.Comparator;
import java.util.TreeSet;
import online.msym.bean.Person;
public class Demo3_TreeSet {
    public static void main(String[] args) {
        //demo1();
        demo2();
    }
    private static void demo2() {
        // 需求:將字符串按照長度排序, (利用匿名內部類對象, 長度從大到小, 長度相同按照字母倒序)
        TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                int num = s2.length() - s1.length(); // 長度為主要條件
                return num == 0 ? s2.compareTo(s1) : num; // 內容為次要條件
            }
        }); 
        ts.add("aaaaaaaa");
        ts.add("z");
        ts.add("wc");
        ts.add("nba");
        ts.add("cba");
        System.out.println(ts);
    }
    private static void demo1() {
        // 需求:將字符串按照長度排序,(傳遞一個自定義的比較器對象)
        TreeSet<String> ts = new TreeSet<>(new CompareByLen()); // Comparator c = new CompareByLen();
        ts.add("aaaaaaaa");
        ts.add("z");
        ts.add("wc");
        ts.add("nba");
        ts.add("cba");
        System.out.println(ts);
    }
}
class CompareByLen /* extends Object */implements Comparator<String> {//實現一個比較器類
    @Override
    public int compare(String s1, String s2) { // 按照字符串的長度比較
        int num = s1.length() - s2.length(); // 長度為主要條件
        return num == 0 ? s1.compareTo(s2) : num; // 內容為次要條件
    }
}

【點擊此處回到主頁】


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM