比较器排序Comparator
案例:存储学生对象并遍历,创建TreeSet集合使用带参构造方法 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
结论: 1、用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的 2、比较器排序:就是让集合的构造方法接收Comparator的实现类对象,重写compare方法,注意compare方法有两个参数 3、重写方法时,一定要注意排序规则(即重写compare方法时里面的方法体),必须按照要求的年龄条件和姓名条件来写
比较器排序Comparator的练习
xxxxxxxxxxpackage ch15;
public class a_10_1Student {
//成员变量 private String name; private int age;
//无参构造方法 public a_10_1Student() { }
//带参构造方法 public a_10_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; }
}xxxxxxxxxxpackage ch15;
import java.util.Comparator;import java.util.TreeSet;
//该案例会优先输出年龄较小的元素(升序,也可去学生类里面改为降序),如果年龄相同就会按照姓名的字母顺序进行排序。该案例会去除重复元素public class a_10_2测试 {
public static void main(String[] args) {
//使用带参构造方法,创建TreeSet集合的对象。 //注意:自然排序是直接在下面那行的TreeSet接口中传递一个Comparator比较器接口,注意用命名内部类的写法,优点是不用在学生类里面写比较器接口 TreeSet<a_10_1Student> ts = new TreeSet<a_10_1Student>(new Comparator<a_10_1Student>() { //参数是两个学生对象,两个学生对象是用来做比较的。下面的compare方法就是我们说的规则 public int compare(a_10_1Student s1, a_10_1Student s2) { //this.age-s.age。这里的s1就相当于this,s2就相当于s int num = s1.getAge() - s2.getAge(); int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num; return num2; } });
//创建学生对象 a_10_1Student s1 = new a_10_1Student("Andy", 17); a_10_1Student s2 = new a_10_1Student("Daniel ", 19); a_10_1Student s3 = new a_10_1Student("Frank ", 18); a_10_1Student s4 = new a_10_1Student("Tom", 18); a_10_1Student s5 = new a_10_1Student("Jack", 19); a_10_1Student s6 = new a_10_1Student("Jack", 19);
//把学生添加进集合 ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6);
//遍历集合,这里使用增强for进行遍历 for (a_10_1Student s : ts) { System.out.println(s.getName() + "," + s.getAge()); //为什么会报错ClassCastException,类转换异常 //原因是学生类不能转换为自然排序接口Comparable,如何解决,如下
//学生类要做自然排序就必须先实现Comparable接口,去学生类那里添加implements Comparable<a_9_1Student> //还需要在学生类里面重写compareTo方法 }
}}