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

猜你喜欢

转载自blog.csdn.net/alai_programmer/article/details/77741907