【背景】 最近一个需求涉及到实体对象中某些属性的修改。其中使用到了Comparator 比较器,在这里总结一下,并做一些扩展。
先上两个代码:
使用Comparator 比较器
/**
* 年龄比较器,根据年龄比较
*/
public class AgeCompator implements Comparator<Student> {
@Override
public int compare(Student stu1, Student stu2) {
return stu1.getAge() - stu2.getAge();
}
}
/**
* 分数比较器(根据分数,进行升序或者降序排序)
*/
public class ScoreCompator implements Comparator<Student>{
@Override
public int compare(Student stu1, Student stu2) {
return stu1.getScore() - stu2.getScore();
}
}
public void compare() {
List<Student> students = new ArrayList<>();
Student stu1 = new Student();
stu1.setScore(100);
stu1.setAge(27);
students.add(stu1);
Student stu2 = new Student();
stu2.setScore(56);
stu2.setAge(29);
students.add(stu2);
Student stu3 = new Student();
stu3.setScore(90);
stu3.setAge(28);
students.add(stu3);
Collections.sort(students, new AgeCompator());
for (Student stu : students) {
System.out.println(stu.getAge());
}
Collections.sort(students, new ScoreCompator());
for (Student stu : students) {
System.out.println(stu.getScore());
}
}
使用Comparable比较
//Student类
@Data
public class Student implements Comparable<Student>{
private Integer age;
private String name;
private Integer score;
@Override
public int compareTo(Student stu) {
return this.getAge() - stu.getAge();
}
}
//比较的功能类
public void compareable(){
List<Student> students = new ArrayList<>();
Student stu1 = new Student();
stu1.setScore(100);
stu1.setAge(27);
students.add(stu1);
Student stu2 = new Student();
stu2.setScore(56);
stu2.setAge(29);
students.add(stu2);
Student stu3 = new Student();
stu3.setScore(90);
stu3.setAge(28);
students.add(stu3);
//在Collections的sort方法这种方式,最后通过student类对象调用了comparable方法。
Collections.sort(students);
for (Student stu : students) {
System.out.println(stu.getAge());
}
}
区别:
1、comparator 是比较器,可以直接执行。采用了策略模式,一个实体对象根据需要设计可以设计多个比较器。隔离性好,方便。
2、comparable 通过比较实体对象来调用的。但是一个实体只能实现一个接口,所以扩展性不是很好,跟类绑定了。
Collection中的Sort方法底层是采用了什么算法?
@SuppressWarnings({"unchecked", "rawtypes"})
public static <T> void sort(List<T> list, Comparator<? super T> c) {
list.sort(c);
}
public static <T> void sort(T[] a, Comparator<? super T> c) {
if (c == null) {
sort(a);
} else {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, 0, a.length, c, null, 0, 0);
}
}
private static <T> void legacyMergeSort(T[] a, Comparator<? super T> c) {
T[] aux = a.clone();
if (c==null)
mergeSort(aux, a, 0, a.length, 0); //归并算法作为排序的
else
mergeSort(aux, a, 0, a.length, 0, c);
}
// Insertion sort on smallest arrays
if (length < INSERTIONSORT_THRESHOLD) {
for (int i=low; i<high; i++)
for (int j=i; j>low &&
((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
swap(dest, j, j-1);
return;
}
如果长度小于INSERTIONSORT_THRESHOLD = 7 就直接采用插入排序。如果大于的话,那么就采用归并排序。