比较器的使用优点:
1)比较器的实质就是重载比较运算符
2)比较器可以很好的应用在特殊标准的排序上,有较大的灵活性(比如我想先按照学生成绩升序排列,当两个学生成绩相等时,我想按照该学生的年龄降序排列)
3)比较器可以很好的应用在根据特殊标准排序的数据结构上,比如堆排序(PriorityQueue)
比较器的潜台词(重点)
// 创建一个按照年龄升序排列的比较器
public static class AgeAscendingComparator implements Comparator<Student>
{
// 潜台词: 返回负数的时候,o1排在前面
// 返回正数的时候,o2排在前面
// 等于0时,谁排在前面无所谓
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}
比较器的使用案例一:PriorityQueue实现降序排列
分析:众所周知,PriorityQueue是默认按照升序排列的,如果要实现按照降序排序,则要用到比较器
public class Comp_heap
{
public static void main(String[] args)
{
PriorityQueue<Integer> heap =new PriorityQueue<>(new HeapDescendingComaparator());
heap.add(10);
heap.add(20);
heap.add(200);
heap.add(2);
heap.add(30);
}
// 创建一个静态内部类,实现从大到小降序排列的比较器
public static class HeapDescendingComaparator implements Comparator<Integer>
{
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
}
}
使用Comparator实现自定义排序
e.g :比如我想先按照学生成绩升序排列,当两个学生成绩相等时,我想按照该学生的年龄降序排列
先创建好实体类
package Pojo;
import lombok.Data;
import lombok.ToString;
@Data
public class Student {
public int age;
public String name;
public int grade;
public Student(int age, String name, int grade)
{
this.age = age;
this.name = name;
this.grade = grade;
}
}
再创建Comparator_create类,在该类的内部新建一个静态内部类或者匿名内部类
使用静态内部类的方式实现
package basic;
import Pojo.Student;
import java.util.Arrays;
import java.util.Comparator;
public class Comparator_create {
// 创建一个按照年龄升序排列的比较器
public static class AgeAscendingComparator implements Comparator<Student>
{
// 潜台词: 返回负数的时候,o1排在前面
// 返回正数的时候,o2排在前面
// 等于0时,谁排在前面无所谓
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}
// 创建一个按照年龄降序排列的比较器
public static class AgeDescendingComparator implements Comparator<Student>
{
// 潜台词: 返回负数的时候,o1排在前面
// 返回正数的时候,o2排在前面
// 等于0时,谁排在前面无所谓
@Override
public int compare(Student o1, Student o2) {
return o2.age - o1.age;
}
}
// 创建一个按照成绩降序排列,但是当成绩相等时按照学生年龄升序排列的比较器
public static class DIYComparator implements Comparator<Student>
{
// 潜台词: 返回负数的时候,o1排在前面
// 返回正数的时候,o2排在前面
// 等于0时,谁排在前面无所谓
@Override
public int compare(Student o1, Student o2) {
if (o2.grade - o1.grade == 0)
return o1.age - o2.age;
return o2.grade - o1.grade;
// 下面是使用三目运算符替换掉上面的if else语句,代码更简洁
//return (o2.grade - o1.grade == 0) ? (o1.age - o2.age) : (o2.grade - o1.grade) ;
}
}
public static void main(String[] args) {
Student student1 = new Student(10, "yxg", 99);
Student student2 = new Student(40, "yxg2", 90);
Student student3 = new Student(20, "yxg3", 91);
Student student4 = new Student(25, "yxg4", 91);
Student[] student = new Student[]{student2, student1, student3, student4};
Arrays.sort(student, new DIYComparator());
for (Student s : student)
{
System.out.println("age: " + s.age + ", grade: "+ s.grade + " , name: " + s.name );
}
}
}
使用匿名内部类的方式实现(如果该比较器只被使用一次,使用匿名内部类实现能达到性能的最大化)
public static void main(String[] args) {
Student student1 = new Student(10, "yxg", 99);
Student student2 = new Student(40, "yxg2", 90);
Student student3 = new Student(20, "yxg3", 91);
Student student4 = new Student(25, "yxg4", 91);
Student[] student = new Student[]{student2, student1, student3, student4};
Arrays.sort(student, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return (o2.grade - o1.grade == 0) ? (o1.age - o2.age) : (o2.grade - o1.grade) ;
}
});
//Arrays.sort(student, new DIYComparator());
for (Student s : student)
{
System.out.println("age: " + s.age + ", grade: "+ s.grade + " , name: " + s.name );
}
}
如果比较器使用的比较多,超过一次,可以把他写成一个工具类
步骤:把静态内部类中的代码拷贝到新的类中,然后去掉static关键字即可
package utils;
public class AgeAscendingComparator implements Comparator<Student>
{
// 潜台词: 返回负数的时候,o1排在前面
// 返回正数的时候,o2排在前面
// 等于0时,谁排在前面无所谓
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}