自然排序Comparable
案例:存储学生对象并遍历,创建TreeSet集合使用无参构造方法 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
结论: 1、用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的 2、自然排序,就是让元素所属的类实现Comparable接口,并且重写compareTo()方法 3、重写方法时,一定要注意排序规则(即重写compareTo方法时里面的方法体),必须按照要求的年龄条件和姓名条件来写
自然排序Comparable的练习
xxxxxxxxxx
package 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;
//上面还有一个优点,就是当年龄和名字都相同时,后来的元素是存储不进去的,即保证了元素的唯一性
}
}
xxxxxxxxxx
package 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方法
}
}
}