比较器排序Comparator
案例:存储学生对象并遍历,创建TreeSet集合使用带参构造方法 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
结论: 1、用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的 2、比较器排序:就是让集合的构造方法接收Comparator的实现类对象,重写compare方法,注意compare方法有两个参数 3、重写方法时,一定要注意排序规则(即重写compare方法时里面的方法体),必须按照要求的年龄条件和姓名条件来写
比较器排序Comparator的练习
xxxxxxxxxx
package 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;
}
}
xxxxxxxxxx
package 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方法
}
}
}