- 比较器的实质就是重载比较运算符
- 比较器可以很好地应用在特殊标准的排序上
- 比较器可以很好地应用在根据特殊标准排序的结构上
- 写代码变得异常容易,还用于泛型编程
自定义的类型实现比较器以明确比较方法:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.TreeMap;
public class MyComparator {
public static class Student {
String name;
int id;
int age;
public Student(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
}
// 任何比较器:
// compare方法里,遵循一个统一的规范:
// 返回负数的时候,认为第一个参数应该排在前面
// 返回正数的时候,认为第二个参数应该排在前面
// 返回0的时候,认为无所谓谁放前面
//年龄升序
public static class AgeAscendingOrder implements Comparator {
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}
//Id降序
public static class IdDescendingOrder implements Comparator {
@Override
public int compare(Student o1, Student o2) {
//if (o1.id > o2.id) {
// return -1;
//} else if (o1.id < o2.id) {
// return 1;
//} else {
// return 0;
//}
return o2.id - o1.id;
}
}
//Id升序年龄降序:id相同时按照年龄降序
public static class IdAscendingAndAgeDescendingOrder implements Comparator {
@Override
public int compare(MyComparator.Student o1, MyComparator.Student o2) {
return o1.id != o2.id ? (o1.id - o2.id) : (o2.age - o1.age);
}
}
public static void main(String[] args) {
Student student1 = new Student("A", 1, 20);
Student student2 = new Student("B", 3, 19);
Student student3 = new Student("C", 2, 25);
Student student4 = new Student("D", 3, 25);
System.out.println("年龄升序排列:");
Student[] students = new Student[]{ student1, student2, student3 };
Arrays.sort(students, new AgeAscendingOrder());
for (int i = 0; i < students.length; i++) {
System.out.println(students[i].name +", " + students[i].id + ", " + students[i].age);
} //B A C
System.out.println("ID降序排列:");
Student[] students1 = new Student[]{ student1, student2, student3 };
Arrays.sort(students1, new IdDescendingOrder());
for (int i = 0; i < students1.length; i++) {
System.out.println(students1[i].name +", " + students1[i].id + ", " + students1[i].age);
}
System.out.println("ID升序年龄降序排列:");
Student[] students2 = new Student[]{ student1, student2, student3, student4 };
Arrays.sort(students2, new IdAscendingAndAgeDescendingOrder());
for (int i = 0; i < students2.length; i++) {
System.out.println(students2[i].name +", " + students2[i].id + ", " + students2[i].age);
}
System.out.println("容器中使用比较器:");
ArrayList stuList = new ArrayList<>();
stuList.add(student1);
stuList.add(student2);
stuList.add(student3);
stuList.add(student4);
stuList.sort(new IdAscendingAndAgeDescendingOrder());
for (int i = 0; i < stuList.size(); i++) {
Student s = stuList.get(i);
System.out.println(s.name +", " + s.id + ", " + s.age);
}
System.out.println("有序结构使用比较器确定比较方式:");
//必须传入比较器,否则连数据都无法添加,因为有序表会按照key进行排序,没有为自定义结构实现比较器,有序表就不知道如何进行排序
TreeMap treeMap = new TreeMap<>(new IdAscendingAndAgeDescendingOrder());
treeMap.put(student1, "I am student1");
treeMap.put(student2, "I am student2");
treeMap.put(student3, "I am student3");
treeMap.put(student4, "I am student4");
for (Student s : treeMap.keySet()) {
System.out.println(s.name +", " + s.id + ", " + s.age);
}
System.out.println("Lambda表达式实现id比较器:");
//这里的比较器只考虑了id,所以相同的id的实例只会被加入一个
TreeMap treeMap1 = new TreeMap<>((a, b) -> a.id - b.id);
treeMap1.put(student1, "I am student1");
treeMap1.put(student2, "I am student2");
treeMap1.put(student3, "I am student3");
treeMap1.put(student4, "I am student4");
for (Student s : treeMap1.keySet()) {
System.out.println(s.name +", " + s.id + ", " + s.age);
}
System.out.println("Lambda表达式实现比较器并在有序表中保留所有实例:");
//计算相同id的也会被保留下来
TreeMap treeMap2 = new TreeMap<>((a, b) -> a.id != b.id ? (a.id - b.id) : (a.hashCode() - b.hashCode()));
treeMap2.put(student1, "I am student1");
treeMap2.put(student2, "I am student2");
treeMap2.put(student3, "I am student3");
treeMap2.put(student4, "I am student4");
for (Student s : treeMap2.keySet()) {
System.out.println(s.name +", " + s.id + ", " + s.age);
}
}
}
运行结果:
年龄升序排列: B, 3, 19 A, 1, 20 C, 2, 25 ID降序排列: B, 3, 19 C, 2, 25 A, 1, 20 ID升序年龄降序排列: A, 1, 20 C, 2, 25 D, 3, 25 B, 3, 19 容器中使用比较器: A, 1, 20 C, 2, 25 D, 3, 25 B, 3, 19 有序结构使用比较器确定比较方式: A, 1, 20 C, 2, 25 D, 3, 25 B, 3, 19 Lambda表达式实现id比较器: A, 1, 20 C, 2, 25 B, 3, 19 Lambda表达式实现比较器并在有序表中保留所有实例: A, 1, 20 C, 2, 25 D, 3, 25 B, 3, 19



