1.知识点了解
Comparator和Comparable都是用用来实现集合中元素的比较、排序的,所以,经常在集合外定义Comparator接口的方法和集合内实现Comparable接口的方法中实现排序
相同点:
二者的比较方法Comparable的compareTo和compare返回的结果有三种负数、零、正数,分别表示的关系为小于、等于、大于
不同点:
Comparator位于java.util包下,属于Collection的一员;Comparable位于java.lang包下
Comparable是一个内部比较器,实现该接口的对象相当于具有了排序的能力;Comparator是一个外部比较器,可以将两个没有实现排序的对象实现Comparator接口来实现排序,内部与外部是相对于排序代码是否在实现的排序的对象中实现的
Comparator接口中的方法如下:
Comparable中的方法如下所示:
建议Comparator实现java.io.Serializable接口从而序列化,因为它们经常在序列化后的TreeSet、TreeMap等数据结构中使用;equals方法经常被重写来比较引用对象是否是同一个;
2.实际应用
实现按照学生的年龄从小到大、如果年龄相等,则按照姓名的字典排序
2.1 通过Comparator外部比较器来实现排序
Student类:
1 public class Student {
2 private String name;
3 private Integer age;
4 public String getName() {
5 return name;
6 }
7 public void setName(String name) {
8 this.name = name;
9 }
10 Student(String name, Integer age){
11 this.name=name;
12 this.age=age;
13 }
14
15 public Integer getAge() {
16 return age;
17 }
18
19 public void setAge(Integer age) {
20 this.age = age;
21 }
22
23 @Override
24 public String toString() {
25 return "Student{" +
26 "name='" + name + '\'' +
27 ", age=" + age +
28 '}';
29 }
Comparator实现排序类:
1 /**
2 * 实现按照学生的年龄从小到大、如果年龄相等,则按照姓名的字典排序
3 */
4 public class StudentCompartor implements Comparator<Student> {
5
6 @Override
7 public int compare(Student s1, Student s2) {
8 return (s1.getAge()-s2.getAge()==0)?(s1.getName().compareTo(s2.getName())):(s1.getAge()-s2.getAge());
9 }
10 public static void main(String[] args){
11 StudentCompartor pc = new StudentCompartor();
12 Student p1=new Student("zhangsan",20);
13 Student p2=new Student("lisi",25);
14 Student p3=new Student("zhangsan",25);
15 if(pc.compare(p1,p2)<0){
16 System.out.println(p1);
17 System.out.println(p2);
18 }else{
19 System.out.println(p2);
20 System.out.println(p1);
21 }
22 //两者年龄相等,按照姓名排序
23 if(pc.compare(p2,p3)<0){
24 System.out.println(p2);
25 System.out.println(p3);
26 }else{
27 System.out.println(p3);
28 System.out.println(p2);
29 }
30 }
31 }
运行结果:
2.2通过Comparable内部比较器来实现排序
Student类:实现了Comparable接口
1 public class Student implements Comparable<Student> {
2 private String name;
3 private Integer age;
4
5 public String getName() {
6 return name;
7 }
8
9 public void setName(String name) {
10 this.name = name;
11 }
12
13 public Integer getAge() {
14 return age;
15 }
16
17 public void setAge(Integer age) {
18 this.age = age;
19 }
20
21 Student(String name, Integer age) {
22 this.name = name;
23 this.age = age;
24 }
25
26 @Override
27 public int compareTo(Student s2) {
28 return (this.getAge() - s2.getAge() == 0) ? (this.getName().compareTo(s2.getName()))
29 : (this.getAge() - s2.getAge());
30 }
31
32 @Override
33 public String toString() {
34 return "Student{" + "name='" + name + '\'' + ", age=" + age + '}';
35 }
36 }
内部比较器Comparable实现的排序:
1 /**
2 * 实现按照学生的年龄从小到大、如果年龄相等,则按照姓名的字典排序
3 */
4 public class StudentComparable {
5 public static void main(String[] args) {
6 Student p1 = new Student("zhangsan", 20);
7 Student p2 = new Student("lisi", 25);
8 Student p3 = new Student("zhangsan", 25);
9 if (p1.compareTo(p2) < 0) {
10 System.out.println(p1);
11 System.out.println(p2);
12 } else {
13 System.out.println(p2);
14 System.out.println(p1);
15 }
16 // 两者年龄相等,按照姓名排序
17 if (p2.compareTo(p3) < 0) {
18 System.out.println(p2);
19 System.out.println(p3);
20 } else {
21 System.out.println(p3);
22 System.out.println(p2);
23 }
24 }
25 }
运行结果同上所示。