java.lang.Comparable 接口中只有一个方法,如下所示
public int compareTo(T o);
什么时候需要实现Comparable接口
当一个类需要对它的实例进行排序时,就需要实现Comparable接口。
通过实现Comparable接口,可以让你的类与所有依赖此接口的通用算法和集合实现进行互操作
几乎Java平台类库中的所有值类(值类只是一个表示值的类,例如Integer或String类)以及所有枚举类型都实现了Comparable接口。 如果你正在编写具有明显自然顺序(如字母顺序,数字顺序或时间顺序)的值类,则应该实现Comparable接口
实现Comparable接口的约定
实现Comparable接口的注意事项写在了方法说明中,可以点击这里查看。
翻译过来要点如下
符号sgn(expression)表示数学中的 signum 函数,它根据表达式的值为负数、零、正数,对应返回-1、0和1。
实现类必须确保所有x和y都满足sgn(x.compareTo(y)) == -sgn(y. compareTo(x))。 (这意味着当且仅当y.compareTo(x)抛出异常时,x.compareTo(y)必须抛出异常。)
实现类还必须确保该关系是可传递的:(x. compareTo(y) > 0 && y.compareTo(z) > 0)意味着x.compareTo(z) > 0。
最后,对于所有的z,实现类必须确保[x.compareTo(y) == 0意味着sgn(x.compareTo(z)) == sgn(y.compareTo(z))。
强烈推荐x.compareTo(y) == 0) == (x.equals(y)),但不是必需的。 一般来说,任何实现了Comparable接口的类违反了这个条件都应该清楚地说明这个事实。 推荐的语言是“注意:这个类有一个自然顺序,与equals不一致”。
正如一个违反hashCode约定的类可能会破坏依赖于哈希的其他类一样,违反compareTo约定的类可能会破坏依赖于比较的其他类。
这三条规定的一个结果是,compareTo方法所实施的平等测试必须遵守equals方法约定所施加的相同限制:自反性,对称性和传递性。
实现Comparable接口的方法和例子
如果一个类有多个重要的属性,那么比较他们的顺序是至关重要的。 从最重要的属性开始,逐步比较所有的重要属性。 如果比较结果不是零(零表示相等),则表示比较完成; 只是返回结果。 如果最重要的字段是相等的,比较下一个重要的属性,依此类推,直到找到不相等的属性或比较剩余不那么重要的属性。
在Java 8中Comparator接口提供了一系列比较器方法,可以使比较器流畅地构建。 这些比较器可以用来实现compareTo方法,就像Comparable接口所要求的那样。
// Comparable with comparator construction methods
private static final Comparator<PhoneNumber> COMPARATOR =
comparingInt((PhoneNumber pn) -> pn.areaCode)
.thenComparingInt(pn -> pn.prefix)
.thenComparingInt(pn -> pn.lineNum);
public int compareTo(PhoneNumber pn) {
return [COMPARATOR.compare(this](http://COMPARATOR.compare(this), pn);
}
Comparator类具有完整的构建方法。对于long和double基本类型,也有对应的类似于comparingInt和thenComparingInt的方法,int版本的方法也可以应用于取值范围小于 int的类型上,如short类型,如PhoneNumber实例中所示。对于double版本的方法也可以用在float类型上。这提供了所有Java的基本数字类型的覆盖。
**// Comparator based on static compare method**
static Comparator<Object> hashCodeOrder = new Comparator<>() {
public int compare(Object o1, Object o2) {
return Integer.compare(o1.hashCode(), o2.hashCode());
}
};
或者使用Comparator的构建方法:
// Comparator based on Comparator construction method
static Comparator<Object> hashCodeOrder =
Comparator.comparingInt(o -> o.hashCode());
总而言之,无论何时实现具有合理排序的值类,你都应该让该类实现Comparable接口,以便在基于比较的集合中轻松对其实例进行排序,搜索和使用。 比较compareTo方法的实现中的字段值时,请避免使用"<"和">"运算符。 相反,使用包装类中的静态compare方法或Comparator接口中的构建方法。
参考文章:
网友评论