第12条:考虑实现Comparable接口
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接口的更多相关文章
- EffectiveJava(12)考虑实现Comparable接口
考虑实现Comparable接口 compareTo方法 Comparable接口的唯一方法,允许进行简单的等同性比较,允许执行顺序比较 Comparable接口被所有值类实现.所以如果一个值类有非常 ...
- Item 12 考虑实现Comparable接口
1.Comparable接口,用来做什么. 2.判定类实现的Comparable接口是否正确的方法. 3.不要扩展一个已经实现了Comparable接口的类来增加用于比较的值组件. 1.Com ...
- 12.Java中Comparable接口,Readable接口和Iterable接口
1.Comparable接口 说明:可比较(可排序的) 例子:按照MyClass的y属性进行生序排序 class MyClass implements Comparable<MyClass> ...
- 第十二条:考虑实现Comparable接口
与前面讨论的方法不同,compareTo()方法并没有在Object类中定义.相反,它是Comparable接口中唯一的方法. 一个类的实例对象要想是可以比较大小的,那么这个类需要实现Comparab ...
- Java6.0中Comparable接口与Comparator接口详解
Java6.0中Comparable接口与Comparator接口详解 说到现在,读者应该对Comparable接口有了大概的了解,但是为什么又要有一个Comparator接口呢?难道Java的开发者 ...
- Effective Java 第三版——14.考虑实现Comparable接口
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- c#命名规范汇总12条
前言 在刚学习c#的时候,在脑子根本就么有命名规范这个概念,有了一定入门的基础,也很难严格要求自己去规范代码的命名,工作后,发现自己的命名和其他人的命名总会有一些出入,总会闹出一些尴尬的笑话,这里汇总 ...
- 十三、实现Comparable接口和new Comparator<T>(){ }排序的实现过程
参考:https://www.cnblogs.com/igoodful/p/9517784.html Collections有两种比较规则方式,第一种是使用自身的比较规则: 该类必须实现Compara ...
- Java - 谨慎实现Comparable接口
类实现了Comparable接口就表明类的实例本身具有内在的排序关系(natural ordering). 因此,该类可以与很多泛型算法和集合实现进行协作. 而我们之需要实现Comparable接口唯 ...
随机推荐
- PHP流程控制(二)
布尔型循环就是为真的时候执行,为假的时候停止 注意:1.循环能够节约大量的代码,提高重用性质2.循环,一定要有退出条件.3.While循环中,在while循环之前必须对变量进行初始化; 单层循环:语法 ...
- 退出程序是跳过屏幕自检 比如 必输 EXIT-COMMAND
控制必须输入可以,但是我退出程序的时候还要求我输入个值才能退出,这太变态了,相信很多同志都在SAP程序中反感过这个问题. 标准程序咱就不说了,忍了,新开发的功能还是要解决这个问题. 办法很简单:MOD ...
- Remove “System Program Problem Detected” Messages From Ubuntu
One of my Ubuntu systems would pop up the following message multiple times after logging in: System ...
- C#-设置label的字体颜色和大小
在进行label的设置的过程中,常常会遇到需要设定label的字体颜色和字体的大小,这就需要用到label的属性:
- jQuery Masonry构建pinterest网站布局注意要点(转)
在愚人码头的博客上看到有关于如何构建pinterest网站的文章,其实就是“图片瀑布流显示”,我试着在本地做了一个,没有什么问题,但是放到公司的网站上就问题多多.一是定位不准确,二是图片显示不完整.但 ...
- Android市场官方的统计信息
做Android应用和游戏,避免不了的要了解市面上的各种android设备的信息,以最大程度的兼容更多的设备. Android市场会定期发布统计信息,包括SDK版本,屏幕大小和分辨率,OpenGL E ...
- c语言实例
#include <stdio.h> int main() { ; ; i=max(j,k); printf("i=%d\n",i); ; } int max(int ...
- 谈谈MVVM和链式网络请求架构
前言 前一段时间一直在学习iOS的架构.为什么呢? 公司的架构一直是MVC,当我们正式上线的时候,项目已经有了超十万行代码.主要的VC一般都有2000行代码以上. 关键是,目前版本我们只做了三分之一的 ...
- multiple build commands for output file
在项目中 我们经常会碰到图片这方面的警告 虽然不影响运行 但是警告太多了也不是很好 其中 图片方面遇到的警告以下面的警告偏多:multiple build commands for output ...
- Linux上安装Squall
Squall是Storm之上的类SQL查询工具,能够将类SQL语句转换成topology,然后提交给Storm运行. 安装Squall前要先安装Java和sbt(simple build tool), ...