一、认识Comparator 与 Comparable
Comparator和Comparable是在Java中用于对象比较和排序的接口。
1.1 Comparable
java
java.lang.Comparable

Comparable接口是在被比较的对象自身中实现的,它定义了对象的自然排序顺序。一个实现了
Comparable接口的类可以通过实现compareTo()方法来定义对象的比较逻辑。
compareTo()方法返回一个负整数、零或正整数,分别表示当前对象小于、等于或大于传入的对象。
Comparable接口在对象的内部提供了默认的比较规则。
1.2 Comparator
java
java.util.Comparator

Comparator接口是一个独立的比较器,它实现了比较逻辑但不需要修改被比较的对象本身。
Comparator接口定义了compare()方法,允许在对象之间进行比较。
Comparator对象可以用于对不同类的对象进行排序,或者对同一类的对象采用不同的排序规则。
Comparator提供了一种外部比较机制,可以在不改变对象定义或创建Comparator实例的情况下,对对象进行排序。
二、Comparator 与 Comparable 有什么区别
看了上面的内容都知道这两个都不是一个玩意儿,但是具体有哪些区别呢,我做了一个表格总结如下:
| 特点 | Comparable接口 |
Comparator接口 |
|---|---|---|
| 实现位置 | 被比较的对象类中 | 独立的比较器类中 |
| 默认排序 | 提供对象的自然排序,默认排序规则 | 没有默认排序规则,需要显式创建Comparator对象 |
| 修改对象 | 改变对象自身的比较逻辑 | 不修改被比较的对象 |
| 多重排序 | 只能定义一种排序方式 | 可以定义多个不同的排序规则 |
可以说一个自已完成比较,一个外部程序实现比较差别而已。 用
Comparator策略模式(strategy design pattern),就不改变对象自身,而用一个策略对象(strategy object)来改变它行为。比如:你想对整数采用绝对值大小来排序,
Integer不符合要求,你不需要去修改Integer类(实际上你也不能这么做)去改变它排序行为,只要使用一个实现了Comparator接口口对象来实现控制它排序就行了。
三、Comparator 和Comparable 分别适用于哪些情况?
3.1 Comparator 接口适用情况
-
外部比较 :当你需要对已有的类进行比较,但无法修改这些类的源代码时,可以使用
Comparator接口来定义比较规则。 -
多重排序 :如果你需要根据不同的比较规则对对象进行排序,可以创建多个
Comparator对象来满足不同的排序需求。 -
定制排序 :当类本身没有实现
Comparable接口,或者你想要覆盖默认的比较规则时,可以使用Comparator接口来定义对象的比较逻辑。 -
动态排序 :
Comparator接口允许你在运行时动态选择不同的比较规则,而不需要修改被比较的对象本身。
3.2 Comparable 接口适用情况
-
自然排序 :当你想要定义对象的默认排序规则时,可以实现
Comparable接口并在compareTo()方法中定义对象的比较逻辑。 -
修改对象 :如果你有权修改对象的类,并且希望改变对象自身的比较逻辑,可以实现
Comparable接口来定义对象的比较方式。 -
单一排序 :
Comparable接口只能定义一种排序规则,适用于不需要多个不同的比较规则的情况。
四、Comparator 和Comparable 使用案例
前面说了那么多,可能大家还是不清晰,下面使用两种案例来演示一下他们的区别:
4.1 使用 Comparator 案例
假设有一个名为
Person的类,你可以创建一个PersonComparator实现Comparator接口,然后在compare()方法中定义比较逻辑,如按照年龄升序排序:
java
class Person {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
- 对自定义类进行排序
java
// 实现接口离开来实现比较
class PersonComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p1.getAge() - p2.getAge();
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Demo {
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
// 添加Person对象到列表
Collections.sort(people, new PersonComparator());
}
}
- 使用匿名内部类进行排序(建议使用,更加简洁)
java
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Demo {
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
// 添加Person对象到列表
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p2.getName().compareTo(p1.getName());
}
});
}
}
4.2 使用 Comparable 案例
假设有一个名为
Student的类,你可以让它实现Comparable接口,并在compareTo()方法中定义按照学号升序排序的逻辑
- 排序实现
java
public class Student implements Comparable<Student> {
/**
* 姓名
*/
private Integer name;
/**
* 年龄
*/
private Integer age;
/**
* 学号
*/
private Integer studentId;
@Override
public int compareTo(Student other) {
return this.studentId - other.studentId;
}
}
- 使用方法
java
public class Test {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
// 添加Student对象到列表
Collections.sort(students);
}
}
五、总结
在使用Comparable接口时,对象自身就具备了默认的比较规则,可以直接使用Collections.sort()或Arrays.sort()等方法进行排序。而使用Comparator接口时,你可以创建多个不同的比较器对象,并通过传递给排序方法来指定使用哪个比较器进行排序。
Comparator和Comparable都提供了灵活的比较和排序机制,实际开发中可以根据具体的需求选择适合的接口来实现对象的比较和排序。
希望本文能给你带来帮助,如有错误或建议,欢迎指正和提出。