TreeSet的两种排序方式

转自:http://blog.csdn.net/xiaofei__/article/details/53138681
1.排序的引入
由于TreeSet可以实现对元素按照某种规则进行排序,例如下面的例子

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);  
            }  
        }  
    }  

运行结果为:

但是对自定义对象呢

 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类:

    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接口
2.重写Comparable接口中的Compareto方法

int compareTo(T o)
比较此对象与指定对象的顺序。

故Student类为:特别注意在重写Compareto方法时,注意排序


    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;  
        }  

    }  

而主类中为:

 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接口
2.重写Comparator接口中的Compare方法
int compare(T o1,T o2)
比较用来排序的两个参数。

3.在主类中使用下面的 构造方法

TreeSet(Comparator<? superE> comparator)
          构造一个新的空 TreeSet,它根据指定比较器进行排序。

主类:

  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类:

  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接口)

    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的内容直接写到主类中

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>接口,重写compare方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值