自然排序Comparable
案例:存储学生对象并遍历,创建TreeSet集合使用无参构造方法 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
结论: 1、用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的 2、自然排序,就是让元素所属的类实现Comparable接口,并且重写compareTo()方法 3、重写方法时,一定要注意排序规则(即重写compareTo方法时里面的方法体),必须按照要求的年龄条件和姓名条件来写
自然排序Comparable的练习
xxxxxxxxxxpackage ch15;
//学生类要做自然排序就必须先实现Comparable接口public class a_9_1Student implements Comparable<a_9_1Student> {
//成员变量 private String name; private int age;
//无参构造方法 public a_9_1Student() { }
//带参构造方法 public a_9_1Student(String name, int age) { this.name = name; this.age = age; }
//成员变量对应的get、set方法 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; }
//学生类要做自然排序还必须要重写compareTo方法 public int compareTo(a_9_1Student s) { //把这行的o改成s,因为我们在测试类的29行用的是s //return 1; //注意这行的返回值要改成1。如果是0的话,测试类里面只能把一个元素存储进集合,原理:集合会认为是重复元素,从而不存储 //返回值是1的话也有一个问题,虽然能把测试类的全部元素存储进集合,但是输出的顺序不是按年龄大小进行输出,而是按存储进的顺序进行输出 //如果把返回值改成-1的话,就是按存储的顺序倒着输出 //总结:0不存储,正数升序存储,负数降序存储
//如何按照年龄大小进行输出呢 //int num = this.age-s.age; //this就是当前准备存储进集合的元素,s就是上一个已经存储进集合的元素。 //return num; //如果上面的num为0,即说明有年龄相同的两个元素,则后者不存储。如为正数,则升序存储。负数则降序存储 //通过测试类的控制台的输出,可以知道this.age-s.age是升序,s.age-this.age是降序 //有一个新问题:就是如果年龄相同的元素,则后者不存储。解决方法如下
//当年龄相同时,还需要再比较姓名内容是否相同 int num = this.age-s.age; //按年龄升序排序 //年龄相同时直接按年龄进行排序。年龄不相同,则由内容调用compareTo方法返回0或整数或负数进行排序 int num2 = num==0?this.name.compareTo(s.name):num; //上面那行的name是字符串,直接调用compareTo方法是可以的。因为:String类实现类Comparable<String>接口 return num2; //上面还有一个优点,就是当年龄和名字都相同时,后来的元素是存储不进去的,即保证了元素的唯一性 }}xxxxxxxxxxpackage ch15;
import java.util.TreeSet;
//该案例会优先输出年龄较小的元素(升序,也可去学生类里面改为降序),如果年龄相同就会按照姓名的字母顺序进行排序。该案例会去除重复元素public class a_9_2测试 {
public static void main(String[] args) {
//使用无参构造方法,创建TreeSet集合的对象 TreeSet<a_9_1Student> ts = new TreeSet<a_9_1Student>();
//创建学生对象 a_9_1Student s1 = new a_9_1Student("Andy", 17); a_9_1Student s2 = new a_9_1Student("Daniel ", 19); a_9_1Student s3 = new a_9_1Student("Frank ", 18); a_9_1Student s4 = new a_9_1Student("Tom", 18); a_9_1Student s5 = new a_9_1Student("Jack", 19); a_9_1Student s6 = new a_9_1Student("Jack", 19);
//把学生添加进集合 ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6);
//遍历集合,这里使用增强for进行遍历 for (a_9_1Student s : ts) { System.out.println(s.getName() + "," + s.getAge()); //为什么会报错ClassCastException,类转换异常 //原因是学生类不能转换为自然排序接口Comparable,如何解决,如下
//学生类要做自然排序就必须先实现Comparable接口,去学生类那里添加implements Comparable<a_9_1Student> //还需要在学生类里面重写compareTo方法 } }}