TreeSet的兩種排序方式

TreeSet的兩種排序方式

1.排序的引入

由於TreeSet可以實現對元素按照某種規則進行排序,例如下面的例子
  1. public class TreeSetDemo {  
  2.     public static void main(String[] args) {  
  3.         // 創建集合對象  
  4.         // 自然順序進行排序  
  5.         TreeSet<Integer> ts = new TreeSet<Integer>();  
  6.   
  7.         // 創建元素並添加  
  8.         // 20,18,23,22,17,24,19,18,24  
  9.         ts.add(20);  
  10.         ts.add(18);  
  11.         ts.add(23);  
  12.         ts.add(22);  
  13.         ts.add(17);  
  14.         ts.add(24);  
  15.         ts.add(19);  
  16.         ts.add(18);  
  17.         ts.add(24);  
  18.   
  19.         // 遍歷  
  20.         for (Integer i : ts) {  
  21.             System.out.println(i);  
  22.         }  
  23.     }  
  24. }  
public class TreeSetDemo {
    public static void main(String[] args) {
        // 創建集合對象
        // 自然順序進行排序
        TreeSet<Integer> ts = new TreeSet<Integer>();

        // 創建元素並添加
        // 20,18,23,22,17,24,19,18,24
        ts.add(20);
        ts.add(18);
        ts.add(23);
        ts.add(22);
        ts.add(17);
        ts.add(24);
        ts.add(19);
        ts.add(18);
        ts.add(24);

        // 遍歷
        for (Integer i : ts) {
            System.out.println(i);
        }
    }
}

運行結果爲:


但是對自定義對象呢?
  1. public class TreeSetDemo02 {  
  2.     public static void main(String[] args) {  
  3.         TreeSet<Student> ts=new TreeSet<Student>();       
  4.         //創建元素對象  
  5.         Student s1=new Student(“zhangsan”,20);  
  6.         Student s2=new Student(“lis”,22);  
  7.         Student s3=new Student(“wangwu”,24);  
  8.         Student s4=new Student(“chenliu”,26);  
  9.         Student s5=new Student(“zhangsan”,22);  
  10.         Student s6=new Student(“qianqi”,24);  
  11.           
  12.         //將元素對象添加到集合對象中  
  13.         ts.add(s1);  
  14.         ts.add(s2);  
  15.         ts.add(s3);  
  16.         ts.add(s4);  
  17.         ts.add(s5);  
  18.         ts.add(s6);  
  19.           
  20.         //遍歷  
  21.         for(Student s:ts){  
  22.             System.out.println(s.getName()+”———–”+s.getAge());  
  23.         }  
  24.     }  
  25. }  
public class TreeSetDemo02 {
    public static void main(String[] args) {
        TreeSet<Student> ts=new TreeSet<Student>();     
        //創建元素對象
        Student s1=new Student("zhangsan",20);
        Student s2=new Student("lis",22);
        Student s3=new Student("wangwu",24);
        Student s4=new Student("chenliu",26);
        Student s5=new Student("zhangsan",22);
        Student s6=new Student("qianqi",24);

        //將元素對象添加到集合對象中
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
        ts.add(s6);

        //遍歷
        for(Student s:ts){
            System.out.println(s.getName()+"-----------"+s.getAge());
        }
    }
}
Student類:
  1. public class Student {  
  2.     private String name;  
  3.     private int age;  
  4.       
  5.     public Student() {  
  6.         super();  
  7.         // TODO Auto-generated constructor stub  
  8.     }     
  9.   
  10.     public Student(String name, int age) {  
  11.         super();  
  12.         this.name = name;  
  13.         this.age = age;  
  14.     }  
  15.   
  16.     public String getName() {  
  17.         return name;  
  18.     }  
  19.   
  20.     public void setName(String name) {  
  21.         this.name = name;  
  22.     }  
  23.   
  24.     public int getAge() {  
  25.         return age;  
  26.     }  
  27.   
  28.     public void setAge(int age) {  
  29.         this.age = age;  
  30.     }  
  31. }  
public class Student {
    private String name;
    private int age;

    public Student() {
        super();
        // TODO Auto-generated constructor stub
    }   

    public Student(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;
    }
}



運行結果:


原因分析:
由於不知道該安照那一中排序方式排序,所以會報錯。

解決方法:
   1.自然排序
2.比較器排序


2.自然排序

自然排序要進行一下操作:

1.Student類中實現  Comparable<T>接口
2.重寫Comparable接口中的Compareto方法

 int compareTo(T o)
          比較此對象與指定對象的順序。

故Student類爲:特別注意在重寫Compareto方法時,注意排序 


  1. package xfcy_04;  
  2. /** 
  3.  * Student類 
  4.  * @author 曉風殘月 
  5.  * 
  6.  */  
  7. public class Student implements Comparable<Student> {  
  8.     private String name;  
  9.     private int age;  
  10.       
  11.     public Student() {  
  12.         super();  
  13.         // TODO Auto-generated constructor stub  
  14.     }     
  15.   
  16.     public Student(String name, int age) {  
  17.         super();  
  18.         this.name = name;  
  19.         this.age = age;  
  20.     }  
  21.   
  22.     public String getName() {  
  23.         return name;  
  24.     }  
  25.   
  26.     public void setName(String name) {  
  27.         this.name = name;  
  28.     }  
  29.   
  30.     public int getAge() {  
  31.         return age;  
  32.     }  
  33.   
  34.     public void setAge(int age) {  
  35.         this.age = age;  
  36.     }  
  37.   
  38.     @Override  
  39.     public int compareTo(Student s) {  
  40.         //return -1; //-1表示放在紅黑樹的左邊,即逆序輸出  
  41.         //return 1;  //1表示放在紅黑樹的右邊,即順序輸出  
  42.         //return o;  //表示元素相同,僅存放第一個元素  
  43.         //主要條件 姓名的長度,如果姓名長度小的就放在左子樹,否則放在右子樹  
  44.         int num=this.name.length()-s.name.length();    
  45.         //姓名的長度相同,不代表內容相同,如果按字典順序此 String 對象位於參數字符串之前,則比較結果爲一個負整數。  
  46.         //如果按字典順序此 String 對象位於參數字符串之後,則比較結果爲一個正整數。  
  47.         //如果這兩個字符串相等,則結果爲 0  
  48.         int num1=num==0?this.name.compareTo(s.name):num;  
  49.         //姓名的長度和內容相同,不代表年齡相同,所以還要判斷年齡  
  50.         int num2=num1==0?this.age-s.age:num1;  
  51.         return num2;  
  52.     }  
  53.       
  54. }  
package xfcy_04;
/**
 * Student類
 * @author 曉風殘月
 *
 */
public class Student implements Comparable<Student> {
    private String name;
    private int age;

    public Student() {
        super();
        // TODO Auto-generated constructor stub
    }   

    public Student(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 int compareTo(Student s) {
        //return -1; //-1表示放在紅黑樹的左邊,即逆序輸出
        //return 1;  //1表示放在紅黑樹的右邊,即順序輸出
        //return o;  //表示元素相同,僅存放第一個元素
        //主要條件 姓名的長度,如果姓名長度小的就放在左子樹,否則放在右子樹
        int num=this.name.length()-s.name.length();  
        //姓名的長度相同,不代表內容相同,如果按字典順序此 String 對象位於參數字符串之前,則比較結果爲一個負整數。
        //如果按字典順序此 String 對象位於參數字符串之後,則比較結果爲一個正整數。
        //如果這兩個字符串相等,則結果爲 0
        int num1=num==0?this.name.compareTo(s.name):num;
        //姓名的長度和內容相同,不代表年齡相同,所以還要判斷年齡
        int num2=num1==0?this.age-s.age:num1;
        return num2;
    }

}


而主類中爲:
  1. package xfcy_04;  
  2.   
  3. import java.util.TreeSet;  
  4.   
  5. /* 
  6. * TreeSet存儲自定義對象並保證排序和唯一。 
  7.  *  
  8.  * 需求:請按照姓名的長度排序 
  9.  */  
  10. public class TreeSetDemo02 {  
  11.     public static void main(String[] args) {  
  12.         //創建集合對象          
  13.         TreeSet<Student> ts=new TreeSet<Student>();  
  14.   
  15.           
  16.         //創建元素對象  
  17.         Student s1=new Student(“zhangsan”,20);  
  18.         Student s2=new Student(“lis”,22);  
  19.         Student s3=new Student(“wangwu”,24);  
  20.         Student s4=new Student(“chenliu”,26);  
  21.         Student s5=new Student(“zhangsan”,22);  
  22.         Student s6=new Student(“qianqi”,24);  
  23.           
  24.         //將元素對象添加到集合對象中  
  25.         ts.add(s1);  
  26.         ts.add(s2);  
  27.         ts.add(s3);  
  28.         ts.add(s4);  
  29.         ts.add(s5);  
  30.         ts.add(s6);  
  31.           
  32.         //遍歷  
  33.         for(Student s:ts){  
  34.             System.out.println(s.getName()+”———–”+s.getAge());  
  35.         }  
  36.     }  
  37. }  
package xfcy_04;

import java.util.TreeSet;

/*
* TreeSet存儲自定義對象並保證排序和唯一。
 * 
 * 需求:請按照姓名的長度排序
 */
public class TreeSetDemo02 {
    public static void main(String[] args) {
        //創建集合對象        
        TreeSet<Student> ts=new TreeSet<Student>();


        //創建元素對象
        Student s1=new Student("zhangsan",20);
        Student s2=new Student("lis",22);
        Student s3=new Student("wangwu",24);
        Student s4=new Student("chenliu",26);
        Student s5=new Student("zhangsan",22);
        Student s6=new Student("qianqi",24);

        //將元素對象添加到集合對象中
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
        ts.add(s6);

        //遍歷
        for(Student s:ts){
            System.out.println(s.getName()+"-----------"+s.getAge());
        }
    }
}


運行結果:


3、比較器排序

比較器排序步驟:
1.單獨創建一個比較類,這裏以MyComparator爲例,並且要讓其繼承Comparator<T>接口
2.重寫Comparator接口中的Compare方法
 int compare(T o1,T o2)
          比較用來排序的兩個參數。

3.在主類中使用下面的 構造方法

TreeSet(Comparator<? superE> comparator)
          構造一個新的空 TreeSet,它根據指定比較器進行排序。

          
主類:

  1. package xfcy_04;  
  2.   
  3. import java.util.TreeSet;  
  4.   
  5. /* 
  6. * TreeSet存儲自定義對象並保證排序和唯一。 
  7.  *  
  8.  * 需求:請按照姓名的長度排序 
  9.  */  
  10. public class TreeSetDemo02 {  
  11.     public static void main(String[] args) {  
  12.         //創建集合對象  
  13.         //TreeSet(Comparator<? super E> comparator) 構造一個新的空 TreeSet,它根據指定比較器進行排序。  
  14.         TreeSet<Student> ts=new TreeSet<Student>(new MyComparator());  
  15.   
  16.         //創建元素對象  
  17.         Student s1=new Student(“zhangsan”,20);  
  18.         Student s2=new Student(“lis”,22);  
  19.         Student s3=new Student(“wangwu”,24);  
  20.         Student s4=new Student(“chenliu”,26);  
  21.         Student s5=new Student(“zhangsan”,22);  
  22.         Student s6=new Student(“qianqi”,24);  
  23.           
  24.         //將元素對象添加到集合對象中  
  25.         ts.add(s1);  
  26.         ts.add(s2);  
  27.         ts.add(s3);  
  28.         ts.add(s4);  
  29.         ts.add(s5);  
  30.         ts.add(s6);  
  31.           
  32.         //遍歷  
  33.         for(Student s:ts){  
  34.             System.out.println(s.getName()+”———–”+s.getAge());  
  35.         }  
  36.     }  
  37. }  
package xfcy_04;

import java.util.TreeSet;

/*
* TreeSet存儲自定義對象並保證排序和唯一。
 * 
 * 需求:請按照姓名的長度排序
 */
public class TreeSetDemo02 {
    public static void main(String[] args) {
        //創建集合對象
        //TreeSet(Comparator<? super E> comparator) 構造一個新的空 TreeSet,它根據指定比較器進行排序。
        TreeSet<Student> ts=new TreeSet<Student>(new MyComparator());

        //創建元素對象
        Student s1=new Student("zhangsan",20);
        Student s2=new Student("lis",22);
        Student s3=new Student("wangwu",24);
        Student s4=new Student("chenliu",26);
        Student s5=new Student("zhangsan",22);
        Student s6=new Student("qianqi",24);

        //將元素對象添加到集合對象中
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
        ts.add(s6);

        //遍歷
        for(Student s:ts){
            System.out.println(s.getName()+"-----------"+s.getAge());
        }
    }
}


MyComparator類:
  1. package xfcy_04;  
  2.   
  3. import java.util.Comparator;  
  4.   
  5. public class MyComparator implements Comparator<Student>{  
  6.   
  7.     @Override  
  8.     public int compare(Student s1,Student s2) {  
  9.         // 姓名長度  
  10.         int num = s1.getName().length() - s2.getName().length();  
  11.         // 姓名內容  
  12.         int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;  
  13.         // 年齡  
  14.         int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;  
  15.         return num3;  
  16.     }  
  17.       
  18.       
  19.       
  20.       
  21. }  
package xfcy_04;

import java.util.Comparator;

public class MyComparator implements Comparator<Student>{

    @Override
    public int compare(Student s1,Student s2) {
        // 姓名長度
        int num = s1.getName().length() - s2.getName().length();
        // 姓名內容
        int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
        // 年齡
        int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
        return num3;
    }




}

學生類(不需要繼承Comparetable接口)
  1. package xfcy_04;  
  2. /** 
  3.  * Student類 
  4.  * @author 曉風殘月 
  5.  * 
  6.  */  
  7. public class Student{  
  8.     private String name;  
  9.     private int age;  
  10.       
  11.     public Student() {  
  12.         super();  
  13.         // TODO Auto-generated constructor stub  
  14.     }     
  15.   
  16.     public Student(String name, int age) {  
  17.         super();  
  18.         this.name = name;  
  19.         this.age = age;  
  20.     }  
  21.   
  22.     public String getName() {  
  23.         return name;  
  24.     }  
  25.   
  26.     public void setName(String name) {  
  27.         this.name = name;  
  28.     }  
  29.   
  30.     public int getAge() {  
  31.         return age;  
  32.     }  
  33.   
  34.     public void setAge(int age) {  
  35.         this.age = age;  
  36.     }  
  37.       
  38. }  
package xfcy_04;
/**
 * Student類
 * @author 曉風殘月
 *
 */
public class Student{
    private String name;
    private int age;

    public Student() {
        super();
        // TODO Auto-generated constructor stub
    }   

    public Student(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;
    }

}


運行結果:





4.比較器修改


由於單獨創建一個類不是特別好,因而可以將MyComparetor的內容直接寫到主類中

  1. public class TreeSetDemo {  
  2.         public static void main(String[] args) {  
  3.                 // 如果一個方法的參數是接口,那麼真正要的是接口的實現類的對象  
  4.         // 而匿名內部類就可以實現這個東西  
  5.         TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {  
  6.             @Override  
  7.             public int compare(Student s1, Student s2) {  
  8.                 // 姓名長度  
  9.                 int num = s1.getName().length() - s2.getName().length();  
  10.                 // 姓名內容  
  11.                 int num2 = num == 0 ? s1.getName().compareTo(s2.getName())  
  12.                         : num;  
  13.                 // 年齡  
  14.                 int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;  
  15.                 return num3;  
  16.             }  
  17.         });  
  18.   
  19.         // 創建元素  
  20.         Student s1 = new Student(“linqingxia”27);  
  21.         Student s2 = new Student(“zhangguorong”29);  
  22.         Student s3 = new Student(“wanglihong”23);  
  23.         Student s4 = new Student(“linqingxia”27);  
  24.         Student s5 = new Student(“liushishi”22);  
  25.         Student s6 = new Student(“wuqilong”40);  
  26.         Student s7 = new Student(“fengqingy”22);  
  27.         Student s8 = new Student(“linqingxia”29);  
  28.   
  29.         // 添加元素  
  30.         ts.add(s1);  
  31.         ts.add(s2);  
  32.         ts.add(s3);  
  33.         ts.add(s4);  
  34.         ts.add(s5);  
  35.         ts.add(s6);  
  36.         ts.add(s7);  
  37.         ts.add(s8);  
  38.   
  39.         // 遍歷  
  40.         for (Student s : ts) {  
  41.             System.out.println(s.getName() + ”—” + s.getAge());  
  42.         }  
  43.     }  
  44. }  
public class TreeSetDemo {
        public static void main(String[] args) {
                // 如果一個方法的參數是接口,那麼真正要的是接口的實現類的對象
        // 而匿名內部類就可以實現這個東西
        TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                // 姓名長度
                int num = s1.getName().length() - s2.getName().length();
                // 姓名內容
                int num2 = num == 0 ? s1.getName().compareTo(s2.getName())
                        : num;
                // 年齡
                int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
                return num3;
            }
        });

        // 創建元素
        Student s1 = new Student("linqingxia", 27);
        Student s2 = new Student("zhangguorong", 29);
        Student s3 = new Student("wanglihong", 23);
        Student s4 = new Student("linqingxia", 27);
        Student s5 = new Student("liushishi", 22);
        Student s6 = new Student("wuqilong", 40);
        Student s7 = new Student("fengqingy", 22);
        Student s8 = new Student("linqingxia", 29);

        // 添加元素
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
        ts.add(s6);
        ts.add(s7);
        ts.add(s8);

        // 遍歷
        for (Student s : ts) {
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }
}


運行結果也如同上面一樣

5.總結

A:自然排序:要在自定義類中實現Comparerable<T>接口  ,並且重寫compareTo方法

B:比較器排序:在自定義類中實現Comparetor<t>接口,重寫

原文鏈接:http://blog.csdn.net/xiaofei__/article/details/53138681

發佈了25 篇原創文章 · 獲贊 12 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章