在昨天我们学习的TreeSet和TreeSet中我们知道它们都是利用红黑树进行有序存储的,那怎么个有序法呢?如果是字符串的话是自然排序的,如果是自定义的对象就必须要实现Comparable接口,不然是会异常的,下面我们来讨论非常相似的Comparable接口和Comparator接口:
1.Comparable接口定义了一个compareTo()方法,自定义的类需要实现这个接口,并重写compareTo()方法,假设我们通过 x.compareTo(y) 来“比较x和y的大小”。若返回“负数”,意味着“x比y小”;返回“零”,意味着“x等于y”;返回“正数”,意味着“x大于y”。具体实现:
public int compareTo(Student other) {
if(id>other.id) {
return 1;
}else if(id<other.id) {
return -1;
}
return 0;
}
如此一下,测试以下代码:
输出结果为:
看来Arrays.sort的默认排序是升序的
2.Comparator接口
如果把Comparable理解为内部比较器的话,那么Comparator可以理解为外部比较器,什么时候需要呢?
例如在学生属性中有id和age,以及name,我们在类里面的CompareTo()方法里定义了按id"比较大小",那么我们在排序时就会按id排序,那么如果我们现在想按age排序怎么搞呢?
这时就需要在外部定义一个Comparator类了,可以简称为比较器,在比较器里定义了Comparator()方法,实现是和CompareTo()方法原理是一样的,我们现在来定义一个AgeComparator类:
这次我们没有来进行比大小的方式,而是使用相减的方式,这样看起来好像非常聪明,但其实它可能会出现减法溢出的BUG,所以我们加以修改:
这样便更加完美,我们现在来使用我们定义的比较器来对刚才的数组进行一次按年龄排序:
测试结果为:
好了,大功告成,实际上,我们在使用时很少自定义一个Comparator类,而是来定义一个匿名类来实现的.