Comparable 和 Comparator比较
简介
Comparable 和 Comparator都是Java中两个接口,comparable 在java.lang包下,comparator在java.util包下,功能都是实现排序,两者虽然功能类似,但是在使用与实现上都有其特点。
Comparable
1.1说明
自然排序Comparable可以认为是一种内部比较器,一般情况下在类定义时实现Comparable接口,重写compareTo方法实现排序,返回值为int类型共有三种情况:
- 当前对象大于传入对象,返回正整数。
- 当前对象小于传入对象,返回负整数。
- 当前对象等于传入对象,返回0。
若当前对象x = 3,传入对象y = 5,返回值为 -1,认为x < y。排列结果由小到大,即为 3,5,实现了升序排列
若当前对象x = 3,传入对象y = 5,返回值为1,认为x > y。排列结果由小到大,即为5,3,实现了降序排列
package java.lang;
import java.util.*;
public interface Comparable<T> {
public int compareTo(T o);
}
1.2举例
实现学生类排序,按年龄排序,年龄相同时,按照姓名字母顺序排序。
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student(){}
public Student(String name, int age){
this.name=name;
this.age=age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int compareTo(Student s){
//按照年龄大小排序
int num = this.age - s.age;//升序
//int num = s.age - this.age;//降序
//年龄一样时,按照姓名字母顺序排序
int num2 =num== 0 ? this.name.compareTo(s.name):num;
return num2;
}
}
Comparator
1.1说明
比较器排序Comparator一般采用内部类的方式实现,需要重写compare方法实现排序。返回值为int类型共有三种情况:
- o1 > o2,返回正整数。
- o1 < o2,返回负整数。
- o1 = o2,返回0。
若o1中x = 3,o2中y = 5,返回值为 -1,认为x < y。排列结果由小到大,即为 3,5,实现了升序排列
若o1中x = 3,o2中y = 5,返回值为1,认为x > y。排列结果由小到大,即为5,3,实现了降序排列
package java.util;
public interface Comparator<T> {
//必须实现的方法
int compare(T o1, T o2);
//选择实现,因为任何类默认实现equals(Object obj)
boolean equals(Object obj);
}
1.2举例
实现了可选择排序方式的优先级队列:
public class PriorityQueueTest {
public static void main(String[] args) {
Queue<Student> queue = new PriorityQueue<>(new StudentCom());
// 匿名内部类方式创建比较器,实现按年龄升序排列
// Queue<Student> queue = new PriorityQueue<>(new Comparator<Student>() {
// @Override
// public int compare(Student o1, Student o2) {
// return o1.getAge() - o2.getAge();
// }
// });
Student stu1 = new Student("张三", 40);
Student stu2 = new Student("李四", 20);
Student stu3 = new Student("王五", 18);
queue.offer(stu1);
queue.offer(stu2);
queue.offer(stu3);
while (!queue.isEmpty()) {
System.out.println(queue.poll());
}
}
}
//内部类实现Comparator接口重写compare方法,实现按年龄升序排列
class StudentCom implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
}
//内部类实现Comparator接口重写compare方法,实现按年龄降序排列
class StudentComDesc implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o2.getAge() - o1.getAge();
}
}
class Student {
private String name;
private int age;
public int getAge() {
return age;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
相同点:
- 两者都是用来用作对象之间的比较,都可以自定义比较规则;
- 两者都是返回一个描述对象之间关系的int;
不同点:
- comparable 在java.lang包下,comparator在java.util包下;
- 实现comparable 必然要重写compareTo(T o)方法,实现comparator必然要重写compare(T o1,T o2)方法;
- Comparator与Comparable同时存在的情况下,比较器Comparator优先级高。
- comparable 在类定义时已经实现,表明这个类具备排序的功能,而comparator是在类没有实现comparable接口或对实现的排序不能满足需求时在类的外部实现。
使用Comparable需要修改原先的实体类,而Comparator 不用修改原先的类直接去实现一个新的比较器 ,因此Comparator实际应用更加广泛。