1. Comparator 和 Comparable作用
Comparator 和 Comparable作用:都是java的接口, 并且是用来对自定义的class比较大小的。
当我们自己定义了一个对象Student:
public class Student {
int score;
int age;
}
有这么一个studentList,里面包含了student1, student2, student3....., 我们用Collections.sort( studentList ), 是得不到预期的结果的. 那为什么可以排序一个字符串list呢?
1.1 stringList为什么可以用Collections.sort() 排序?
public class Test {
public static void main(String[] args) {
List<String> stringList = new ArrayList<>();
stringList.add("hello1");
stringList.add("hello2");
stringList.add("hello3");
Collections.sort(stringList);
System.out.println(stringList.toString());
}
}
执行结果:
[hello1, hello2, hello3]
Process finished with exit code 0
我们看一下String的源码:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
...
}
Collections.sort(stringList);能够得到正确的排序, 那是因为 String 这个对象已经帮我们实现了Comparable接口,所以我们的 Student如果想排序, 也要实现一个比较器。其中,String中compareTo() 实现如下:
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
1.2 自定义对象如何实现排序?是实现比较器
所以,实现对自定义类的排序就是使用Comparator 和 Comparable接口。
2.接口说明
2.1comparator接口:
int compare(T o1, T o2);
2.2 Comparable接口:
public int compareTo(T o);
3. 使用
3.1 使用Comparator 比较器.
Comparator 是定义在Student的外部的, 此时我们的Student类的结构不需要有任何变化
public class Student {
int score;
int age;
//getter() and setter() ...
}
//定义两个比较器
/**
* 分数比较器(根据分数,进行升序或者降序排序)
*/
public class ScoreCompartor implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.score - o2.score;
}
}
/**
* 年龄比较器,根据年龄比较
*/
public class AgeComparator implements Comparator<Student> {
@Override
public int compare(Student p1, Student p2) {
return (p1.age - p2.age);
}
}
//比较
public class Main {
public static void main(String[] args) {
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);
System.out.println("按照年龄排序");
Collections.sort(students, new AgeComparator());
for (Student stu : students) {
System.out.println(stu.getAge());
}
System.out.println("按照分数排序");
Collections.sort(students, new ScoreCompartor());
for (Student stu : students) {
System.out.println(stu.getScore());
}
}
}
执行结果:
按照年龄排序
27
28
29
按照分数排序
56
90
100
Process finished with exit code 0
平时使用的更多的一种方法如下,
public class Main2 {
public static void main(String[] args) {
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 Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
});
System.out.println("按照年龄排序");
for (Student stu : students) {
System.out.println(stu.getAge());
}
Collections.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getScore() - o2.getScore());
}
});
System.out.println("按照分数排序");
for (Student stu : students) {
System.out.println(stu.getScore());
}
}
}
3.2 使用comparable
实现Comparable接口要覆盖compareTo方法, 在compareTo方法里面实现比较
public class Student implements Comparable<Student> {
private int age;
private int score;
@Override
public int compareTo(Student o) {
return this.getAge() - o.getAge() ;
}
}
public class Main {
public static void main(String[] args) {
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);
System.out.println("按照年龄排序");
for (Student stu : students) {
System.out.println(stu.getAge());
}
}
}
执行结果:
按照年龄排序
27
28
29
Process finished with exit code 0
4. comparator和comparable区别
comparator 是比较器,可以直接执行。采用了策略模式,一个实体对象根据需要设计可以设计多个比较器。隔离性好,方便。
comparable 通过比较实体对象来调用的。但是一个实体只能实现一个接口,所以扩展性不是很好,跟类绑定了。
还有很多,看一下Collections.sort() 源代码 https://blog.csdn.net/u010859650/article/details/85009595