第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接口唯 ...
随机推荐
- 实例:ABAP Tree Control 使用与ALV Grid对象关联
Tree Control 是最常用的Windows控件之一,在其他语言中成为"Tree View"等,ABAP的 Tree Contiol 能实现类似的功能. 本文主要介绍一下内容 ...
- cocos2d-x 屏幕坐标系和OPenGL坐标系转换
转自:http://home.cnblogs.com/group/topic/57609.html cocos2d坐标系(OPenGL坐标系):以左下角为原点,x向右,y向上 屏幕坐标系(androi ...
- Linux内核之内存管理(4)--缺页处理程序
本文主要解说缺页处理程序,凝视足够具体,不再解释. //以下函数将一页内存页面映射到指定线性地址处,它返回页面的物理地址 //把一物理内存页面映射到线性地址空间指定处或者说把线性地址空间指定地址add ...
- iOS开发笔记系列-基础1(数据类型与表达式)
学习iOS开发快两年了,去年完成MagViewer之后就因为公司的其他业务繁重,除了维护这个应用之外,只是断断续续地自己做一些实验开发,没有再发布新的应用,这里想整理一下学习过程中的笔记,以便加深印象 ...
- 基于新浪sae使用php生成图片发布图文微博
1.生成图片的代码: <?php header ("Content-type: image/png"); mb_internal_encoding("UTF-8&q ...
- [node.js]RPC(远程过程调用)的实现原理
刚接触到RPC(远程过程调用),就是可以在本地调用远程机子上的程序的方法,看到一个简单的nodejs实现,用来学习RPC的原理很不错:nodejs light_rpc 使用示例: //服务端 ...
- android120 zhihuibeijing 开机页面
软件启动旋转动画: 布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ...
- careercup-中等难度 17.6
17.6 给定一个整数数组,编写一个函数,找出索引m和n,只要将m和n之间的元素排好序,整个数组就是有序的.注意:n越小越好,也就是说,找出符合条件的最短序列. 解法: 开始解题之前,让我们先确认一下 ...
- Logistic Regression and Classification
分类(Classification)与回归都属于监督学习,两者的唯一区别在于,前者要预测的输出变量\(y\)只能取离散值,而后者的输出变量是连续的.这些离散的输出变量在分类问题中通常称之为标签(Lab ...
- mysql事务问题
mysql事务: 若mysql 开启事务后START TRANSACTION ,不显示提交commit,则默认自动回滚,而不是默认自动提交.