Comparable和Comparator接口简介
Comparable接口和Comparator接口的作用 : 用于给实现类规范比较(排序)的方法.
首先看两个接口的代码:
Comparable接口
public interface Comparable<T> {
public int compareTo(T o);
}
Comparator接口
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
//其他默认方法和静态方法;
//......
}
比较两个接口的代码,我们可以看到:
1.Comparable的compareTo(T)方法只有1个参数,.
2.Comparator接口的compare(T o1, T o2)方法有两个参数, 有@FunctionalInterface接口,所以有Lambda表达式的用法
所以,
Comparable只能在类内部实现比较功能,让想让实现比较功能的类自身实现Comparable接口
Comparator可以做成比较器类,让比较器类实现Comparator接口
Comparator接口为什么有多个抽象方法还被标注为函数式接口?
compare(T o1, T o2)方法外的另一个抽象方法equals(Object obj)是Object类的方法,因此所有类都有该方法,不影响Comparator作为函数式接口(瞎猜的).
*接口并非继承自Object,只是接口定义了一套与Object完全相同的方法(详细内容可以网上查询一下,这里暂不讨论)
Comparable或Comparator实现集合的排序功能
Comparable :
1.用Collections工具类的sort()重载方法实现排序!
让希望实现排序功能的类继承Comparable接口,并实现compareTo(T o1)方法,这样该类就具有排序的功能了,所以可以调用Collections类的sort(List<T> list)方法实现自定义排序
@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>> void sort(List<T> list) {...}
Comparator :
1.实现Comparator接口,专门写一个比较器类来实现类的比较功能,将比较器类的对象传入sort()方法
1).Collections的重载sort()方法排序
2).集合的sort()方法支持传入比较器的对象实现排序.
2.以匿名内部类或Lambda表达式的方式来使用.
写一个Lambda表达式的例子:
List<Person> list = new ArrayList<Person>();
list.sort((a, b)-> {
int aId = a.getId();
int bId = b.getId();
int res = aId -bId;
if(res > 0) return 1;
if(res < 0) return -1;
return 0;} );
System.out.println(list);
比较器类的示例
public class PersonComparator<T extends Person> implements Comparator<T> {
@Override
public int compare(T o1, T o2) {
int o1_id = o1.getId();
int o2_id = o2.getId();
if(o1_id == o2_id) return 0;
if(o1_id > o2_id) return 1;
else return -1;
}
}
两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,
但是需要修改源代码, 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义
的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自
己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了