【自然排序】

 1 package com.hxl; 
 2  
 3 public class Student implements Comparable<Student> { 
 4  
 5     private String name; 
 6     private int age; 
 7  
 8     public Student() { 
 9         super(); 
10     } 
11  
12     public Student(String name, int age) { 
13         super(); 
14         this.name = name; 
15         this.age = age; 
16     } 
17  
18     public String getName() { 
19         return name; 
20     } 
21  
22     public void setName(String name) { 
23         this.name = name; 
24     } 
25  
26     public int getAge() { 
27         return age; 
28     } 
29  
30     public void setAge(int age) { 
31         this.age = age; 
32     } 
33  
34     @Override 
35     public int compareTo(Student s) { 
36         // 先让两个对象的age属性做差比较,这个是主要排序条件 
37         int num = this.age - s.age; 
38         // 若age属性相同,再比较name属性(String类本身实现了Comparable接口) 
39         // 即在主要排序条件相同的情况下,次要排序条件起作用 
40         int flag = num == 0 ? this.name.compareTo(s.name) : num; 
41         // 返回比较结果 
42         return flag; 
43     } 
44 }
 1 package com.hxl; 
 2  
 3 import java.util.TreeSet; 
 4  
 5 public class Test { 
 6     public static void main(String[] args) { 
 7         //这里使用的无参构造实例化TreeSet集合,则默认启用的是自然排序 
 8         TreeSet<Student> ts = new TreeSet<Student>(); 
 9         ts.add(new Student("cc", 11)); 
10         ts.add(new Student("ee", 11)); 
11         ts.add(new Student("cc", 22)); 
12         ts.add(new Student("aa", 22)); 
13         ts.add(new Student("bb", 11)); 
14  
15         for (Student s : ts) { 
16             System.out.println(s.getName()+"_"+s.getAge()); 
17         } 
18  
19         /* 
20             为什么TreeSet集合中的元素既唯一又有序呢? 
21             原因是它在存储元素的时候就是有序存储的(红黑树结构存储) 
22             TreeSet的add()方法底层依赖的是Comparable的compareTo方法 
23             这里就是说元素类本身要有自己的compareTo方法 
24             所以元素类本身必须实现Comparable接口,重写compareTo方法 
25             compareTo方法有个特点:它返回的是int型数据,结果有三类负数、0、正数 
26             例如:(Java中一些常见的有比较意义的一些类都实现了Comparable接口,如Integer类) 
27                 Integer a = new Integer(10); 
28                 Integer b = new Integer(20); 
29                 int num = a.compareTo(b);     //因为a小于b,所以num返回的是负数 
30             而TreeSet的add()方法这样理解此返回值: 
31             即返回负数则比根节点小,元素在此集合中唯一,元素存放根的左孩子 
32             返回正数则比根节点大,元素在此集合中唯一,元素存放根的右孩子 
33             返回0则表示,元素相同,在此集合中不唯一,故而丢掉不存放 
34             由此可见,我们的重写的compareTo()方法决定了TreeSet集合中元素的去留和顺序! 
35         */ 
36     } 
37 }

【比较器排序(外部类实现)】

 1 package com.hxl; 
 2  
 3 public class Student{ 
 4  
 5     private String name; 
 6     private int age; 
 7  
 8     public Student() { 
 9         super(); 
10     } 
11  
12     public Student(String name, int age) { 
13         super(); 
14         this.name = name; 
15         this.age = age; 
16     } 
17  
18     public String getName() { 
19         return name; 
20     } 
21  
22     public void setName(String name) { 
23         this.name = name; 
24     } 
25  
26     public int getAge() { 
27         return age; 
28     } 
29  
30     public void setAge(int age) { 
31         this.age = age; 
32     } 
33 }
 1 package com.hxl; 
 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         // 先让两个对象的age属性做差比较,这个是主要排序条件 
10         int num = s1.getAge() - s2.getAge(); 
11         // 若age属性相同,再比较name属性(String类本身实现了Comparable接口) 
12         // 即在主要排序条件相同的情况下,次要排序条件起作用 
13         int flag = num == 0 ? s1.getName().compareTo(s2.getName()) : num; 
14         // 返回比较结果 
15         return flag; 
16     } 
17 }
 1 package com.hxl; 
 2  
 3 import java.util.TreeSet; 
 4  
 5 public class Test { 
 6     public static void main(String[] args) { 
 7         //这里使用TreeSet(Comparator comparator)构造实例化TreeSet集合,则启用的是指定比较器排序 
 8         TreeSet<Student> ts = new TreeSet<Student>(new MyComparator()); 
 9         ts.add(new Student("cc", 11)); 
10         ts.add(new Student("ee", 11)); 
11         ts.add(new Student("cc", 22)); 
12         ts.add(new Student("aa", 22)); 
13         ts.add(new Student("bb", 11)); 
14  
15         for (Student s : ts) { 
16             System.out.println(s.getName()+"_"+s.getAge()); 
17         } 
18     } 
19 }

【比较器排序(内部类实现,如果只使用一次的话)】

 1 package com.hxl; 
 2  
 3 public class Student{ 
 4  
 5     private String name; 
 6     private int age; 
 7  
 8     public Student() { 
 9         super(); 
10     } 
11  
12     public Student(String name, int age) { 
13         super(); 
14         this.name = name; 
15         this.age = age; 
16     } 
17  
18     public String getName() { 
19         return name; 
20     } 
21  
22     public void setName(String name) { 
23         this.name = name; 
24     } 
25  
26     public int getAge() { 
27         return age; 
28     } 
29  
30     public void setAge(int age) { 
31         this.age = age; 
32     } 
33 }
 1 package com.hxl; 
 2  
 3 import java.util.Comparator; 
 4 import java.util.TreeSet; 
 5  
 6 public class Test { 
 7     public static void main(String[] args) { 
 8         //如果一个方法的参数是接口,那么真实想要的是其实是接口实现类的对象 
 9         //这里的对象只用一次,专门定义一个外部类显得麻烦 
10         //匿名内部类可以实现这个需求 
11         TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>(){ 
12             public int compare(Student s1, Student s2) { 
13                 // 先让两个对象的age属性做差比较,这个是主要排序条件 
14                 int num = s1.getAge() - s2.getAge(); 
15                 // 若age属性相同,再比较name属性(String类本身实现了Comparable接口) 
16                 // 即在主要排序条件相同的情况下,次要排序条件起作用 
17                 int flag = num == 0 ? s1.getName().compareTo(s2.getName()) : num; 
18                 // 返回比较结果 
19                 return flag; 
20             } 
21         }); 
22         ts.add(new Student("cc", 11)); 
23         ts.add(new Student("ee", 11)); 
24         ts.add(new Student("cc", 22)); 
25         ts.add(new Student("aa", 22)); 
26         ts.add(new Student("bb", 11)); 
27  
28         for (Student s : ts) { 
29             System.out.println(s.getName()+"_"+s.getAge()); 
30         } 
31     } 
32 }

 【注】开发中会用最后一种,因为第一种只有固定的排序方式,第二种每次都要定义外面类显得麻烦。


发布评论
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

JDK5的新特性之可变参数&Arrays.asList()方法知识解答
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。