CompareTo方法没有在Object中声明,它是Comparable接口中的唯一的方法,不但允许进行简单的等同性比较,而且允许执行顺序比较。类实现了Comparable接口,就表明它的实例具有内在的排序关系。为实现Comparable接口的对象排序:Arrays.sort(a);

一旦实现了Comparable接口,它可以跟许多泛型算法以及依赖于该接口的集合实现进行协作,只需付出很小的努力就可以获得非常强大的功能。Java平台的所有值类都实现了Comparable接口。如果一个类具有明显的内在排序关系,比如按字母顺序,按数字顺序,按年代顺序,就应该实现这个接口。

Integer

CompareTo方法的通用约定:

将这个对象与指定的对象进行比较。当该对象小于、等于、大于指定对象的时候,分别返回一个负整数、零或者正整数。如果由于指定对象的类型而无法与该对象进行比较,则抛出ClassCastException异常。

下面说明中,符号sgn(表达式)表示数学中的signum函数,根据表达式的值为负值、零和正值,分别返回-1、0和1。

1.所有的x和y都满足sgn(x.compareTo(y)) == -sgn(y.compareTo(x))

2.比较关系可传递: (x.compareTo(y) > 0 && y.compareTo(z) > 0) 暗示着x.compareTo(z) > 0

3.确保x.compareTo(y) == 0 暗示着所有的z都满足 sgn(x.compareTo(z)) == sgn(y.compareTo(z))

4.建议(x.compareTo(y) == 0) == (x.equals(y)),但这不是必要的,但是如果违反了这个条件,应该给予明确说明。

就像违反hashCode约定会破坏其他依赖于散列做法的类一样,违反compareTo约定的类也会破坏其他依赖于比较关系的类,依赖于比较关系的类包括有序集合类TreeSet和TreeMap,以及工具类Collections和Arrays,它们内部包含有搜索和排序算法。

compareTo第一条约定指出,如果颠倒两个对象引用之间的比较方向,它们返回的结果是取相反数;第二条指出,如果第一个对象大于第二个对象,并且第二个对象大于第三个对象,那么第一个对象一定大于第三个对象,第三条指出,如果被认为相等的两个对象,它们跟别的对象比较一定会产生相同的结果。

这三条约定导致的结果是,无法再用新的值组件扩展可实例化的类时,同时保持compareTo约定,除非愿意放弃面向对象的抽象优势,针对equals的权宜之计也适用于compareTo方法,编写一个不相关的类,其中包含第一个类的一个实例,然后提供一个视图方法返回这个实例,这样就可以自由地在第二个类上实现compareTo方法,同时也允许它的客户端在必要的时候,把第二个类的实例视同第一个类的实例。

第四条是一个建议,考虑BigDecimal类,它的compareTo方法和equals不一致,如果创建HashSet实例,并添加new BigDecimal("1.0") 和 new BigDecimal("1.00"),这个集合就将包含两个元素,因为HashSet通过equals比较是不相等的,然而,使用TreeSet来执行同样的过程,集合只包含一个元素,因为它是通过compareTo方法进行比较的。

例子:

public final class CaseInsensitiveString implements Comparable<CaseInsensitiveString> {
public int compareTo(CaseInsensitiveString cis) {
return String.CASE_INSENSITIVE_ORDER.compare(s, cis.s);
}
}

如果一个类有多个关键域,必须从最重要的域开始,逐步进行到所有的重要域,如果某个域产生了非零的结果,则整个比较操作结束。比如PhoneNumber类的compareTo方法:

public int compareTo(PhoneNumber pn) {
if(areaCode < pn.areaCode)
return -1;
if(areaCode > pn.areaCode)
return 1; if(prefix < pn.prefix)
return -1;
if(prefix > pn.prefix)
return 1; if(lineNumber < pn.lineNumber)
return -1;
if(lineNumber > pn.lineNumber)
reuturn 1; return 0;
}

第12条:考虑实现Comparable接口的更多相关文章

  1. EffectiveJava(12)考虑实现Comparable接口

    考虑实现Comparable接口 compareTo方法 Comparable接口的唯一方法,允许进行简单的等同性比较,允许执行顺序比较 Comparable接口被所有值类实现.所以如果一个值类有非常 ...

  2. Item 12 考虑实现Comparable接口

    1.Comparable接口,用来做什么. 2.判定类实现的Comparable接口是否正确的方法. 3.不要扩展一个已经实现了Comparable接口的类来增加用于比较的值组件.     1.Com ...

  3. 12.Java中Comparable接口,Readable接口和Iterable接口

    1.Comparable接口 说明:可比较(可排序的) 例子:按照MyClass的y属性进行生序排序 class MyClass implements Comparable<MyClass> ...

  4. 第十二条:考虑实现Comparable接口

    与前面讨论的方法不同,compareTo()方法并没有在Object类中定义.相反,它是Comparable接口中唯一的方法. 一个类的实例对象要想是可以比较大小的,那么这个类需要实现Comparab ...

  5. Java6.0中Comparable接口与Comparator接口详解

    Java6.0中Comparable接口与Comparator接口详解 说到现在,读者应该对Comparable接口有了大概的了解,但是为什么又要有一个Comparator接口呢?难道Java的开发者 ...

  6. Effective Java 第三版——14.考虑实现Comparable接口

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  7. c#命名规范汇总12条

    前言 在刚学习c#的时候,在脑子根本就么有命名规范这个概念,有了一定入门的基础,也很难严格要求自己去规范代码的命名,工作后,发现自己的命名和其他人的命名总会有一些出入,总会闹出一些尴尬的笑话,这里汇总 ...

  8. 十三、实现Comparable接口和new Comparator<T>(){ }排序的实现过程

    参考:https://www.cnblogs.com/igoodful/p/9517784.html Collections有两种比较规则方式,第一种是使用自身的比较规则: 该类必须实现Compara ...

  9. Java - 谨慎实现Comparable接口

    类实现了Comparable接口就表明类的实例本身具有内在的排序关系(natural ordering). 因此,该类可以与很多泛型算法和集合实现进行协作. 而我们之需要实现Comparable接口唯 ...

随机推荐

  1. Triangles

    1010: Triangles Time Limit: 2 Sec   Memory Limit: 128 MB Submit: 18   Solved: 8 Description You are ...

  2. 设置UITabBarController的背景颜色

    if (IOS7) { self.tabBarController.tabBar.barTintColor = kTAB_BAR_GB_COLOR; }else{ self.tabBarControl ...

  3. 远程重启IIS服务

    方法一: $UserName = "administrator" $serverpass = "pass" $server = "10.4.19.60 ...

  4. 找回丢失的SQL Server性能计数器

    There was one time when I was delivering a Service using a tool that gathers performance data throug ...

  5. Centos内核升级的三种方法

    本文出自 “存储之厨” 博客,请务必保留此出处http://xiamachao.blog.51cto.com/10580956/1755354 在基于CentOS平台的工作过程中,难免有时需要升级或者 ...

  6. mysqldump原理5

    http://blog.csdn.net/niu870781892/article/details/6186078 导出多张表的时候表之间用空格分开: # mysqldump -h192.168.25 ...

  7. 假设有两个包含整数的vector对象,编写一段程序,检验其中一个vector对象是否是另一个的前缀。

    #include<iostream> #include<string> #include<vector> using namespace std; int main ...

  8. 文件和目录之access函数

    本篇博文内容摘自<UNIX环境高级编程>(第二版),仅作个人学习记录所用.关于本书可参考:http://www.apuebook.com/. 当用open函数打开一个文件时,内核以进程的有 ...

  9. Tomcat 配置 Probe 监控

    转至:http://9771104.blog.163.com/blog/static/19446622009811112836524/ 手上接触Tomcat的项目越来越多,虽说tomcat的manag ...

  10. Routes

    Routes Routing lets you create your own URL paths, based on the path you can load a closure or a con ...