Comparable接口定义
Comparable是排序接口,如果一个类实现了Comparable接口,意味着这个类是支持排序的,即实现这个类的对象的List或Array可以通过Collections.sort或Arrays.sort进行排序。
Comparable接口来自java.lang包,它仅仅只有一个方法:
package java.lang;
public interface Comparable<T> {
int compareTo(T var1);
}
这个方法的意思是,假设我们使用x.compareTo(y)
来比较x
和y
的大小,若返回负数,意味着x
小于y
;若返回正数,意味着x
大于y
;若返回0,意味着两者相等。
Comparator接口定义
Comparator是比较器接口,在我们需要控制某个没有实现Comparable接口的类的次序时使用。
Comparator接口在Java8中进行了较大的改进,在Java8之前Comparator接口也仅只有两个函数:compare()和equals(),但在Java8中达到了18个方法。不过,其余的方法都是接口的default方法以及static静态方法,所以并不需要在实现时额外实现。对于equals方法,其实也不需要额外的实现。原因是所有类都继承自java.lang.Object这个类,而Object中已经实现了equals方法,那么我们的这个匿名内部类自然不需要实现equals方法。所以在实现Comparator接口时,必须实现的只有Compare方法。
Java中比较器升序降序的实现
对于compare方法,它与compareTo方法类似。在自定义比较器时,总是将升序降序弄混,有必要总结一下。
public int compare(Customer o1, Customer o2) {}
这个函数有两个参数用于比较:
- 当返回负数时,表示不需要交换o1和o2的位置,依旧是o1排在o2前面,升序。
- 当返回正数时,表示需要交换o1和o2的位置,o2排在o1前面,降序。
下面用一段实现Comparator用作匿名内部类的代码作为举例:
import java.util.*;
public class Customer {
private String name;
private int age;
public Customer (String name, int age) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
Customer customer1 = new Customer("James", 23);
Customer customer2 = new Customer("Durante", 35);
List<Customer> list = new ArrayList<>();
list.add(customer1);
list.add(customer2);
list.sort(new Comparator<Customer>() {
@Override
public int compare(Customer o1, Customer o2) {
// 若返回负数,表示不需要交换o1和o2的位置
// return o1.age - o2.age;
// 若返回正数,表示需要交换o1和o2的位置
return o2.age - o1.age;
}
});
for (Customer customer : list)
System.out.println("name: " + customer.getName() + " age: " + customer.getAge());
}
}
得到的结果为:
name: Durante age: 35
name: James age: 23
解释一下,这个函数中的重写的compare方法用于实现降序:
-
在这个函数中,若
o1.age > o2.age
,那么o2.age - o1.age < 0
,返回负数,不需要交换o1和o2的顺序,降序 -
同样,若
o1.age < o2.age
,那么o2.age - o1.age > 0
,返回正数,需要交换o1和o2的顺序,还是降序。
总结
Java中有两种排序方式:
- Comparable 是自然排序。(在实体类中实现)
- Comparator 是定制排序。(不修改实体类,直接在调用方创建)
一些普通数据类型已经实现了Comparable接口,如String, Integer, Double等,我们可以直接调用。而对于一些我们自定义的类,在不同的情况下可能需要不同的比较策略,不能在类中将Comparable定死,这时候通常在调用方创建Comparator进行定制排序。
over~
网友评论