前言
在解读TreeMap源码时,比较器是构造函数的一个参数,如果缺省表示,采用默认比较器。本文笔者来聊聊元素的排序的两个常用接口Comparable和Comparator。
Comparable
comparable接口是一个,内部比较器。由于-able是形容词的后缀,因此,它是领域模型中简单对象的特征。因此也叫作内部比较器。如下代码所示,
1 public class BaseDomain implements Comparable { 2 3 @Override 4 public int compareTo(Object o) { 5 return 0; 6 } 7 }
内部比较器,只要在我们的简单domain对象中实现Comparable接口即可。同时我们的domain对象需要实现compateTo方法。如上所示。Comparable是一个泛型接口,一般情况下,以简单对象作为泛型,如下所示,
1 public class BaseDomain implements Comparable<BaseDomain> { 2 3 @Override 4 public int compareTo(BaseDomain o) { 5 return 0; 6 } 7 }
指定泛型的好处是在compareTo时,不需要强制转型。此处要注意的是,Comparable中的泛型不一定是类本身,也可以是其他的对象,比如String,Integer,Class,Annotation等。总之,除了基础数据类型之外,其他类型都可以。只要在实际业务中,泛型的实际类型和比较的算法能够相适配就可以了。
然而这种内部比较器违背了六大设计原则中的开闭的原则,即已经交付的类中,我们不适合去修改,或者这个类甚至不是我们内部的类,而是其他系统的类,我们更加不能修改,因此。内部比较器显得非常的被动,于是,出现了外部比较器。Comparator。
Comparator
Compatator是外部比较器,以-or结尾,这个比较器则是名词,是第三方的比较器,作为平台性质的参与者。代码如下所示,
1 public class BaseDomainComparator implements Comparator { 2 @Override 3 public int compare(Object o1, Object o2) { 4 5 6 return 0; 7 } 8 }
同样,和Comparable接口一样,也是一个泛型接口,因此我们制定泛型为BaseDomain。
1 public class BaseDomainComparator implements Comparator<BaseDomain> { 2 @Override 3 public int compare(BaseDomain o1, BaseDomain o2) { 4 5 6 return 0; 7 } 8 }
一般的,如果o1大于02返回正数,如果01小于02返回负数,如果相等,返回0。这个比较器,不是简单对象独有的,因此如果需要比较,需要拥有两个或两个以上的对象,而且,这些对象的类型比较要一直。因此这个比较器的命名往往是 简单对象+Comparator来命名。在Java源代码中,最常见的就是Arrays.sort中作为比较器参数进行排序。而在TreeMap源码中的私有成员属性也定义了一个比较器private final Comparator<? super K> comparator;因此,comparator比较器,是一个松耦合的比较器。