第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接口唯 ...
随机推荐
- Castle IOC FOR MVC 使用方法
Castle Web.API 使用方法 一.创建 WindsorActivator 继承 IHttpControllerActivator public class WindsorActivator ...
- Android硬件加速
Android从3.0(API Level 11)开始,在绘制View的时候支持硬件加速,充分利用GPU的特性,使得绘制更加平滑,但是会多消耗一些内存. 开启或关闭硬件加速: 由于硬件加速自身并非完美 ...
- nginx利用image_filter动态生成缩略图
转自:http://www.nginx.cn/2160.html "我如今是有些图片须要生成缩略图.这个如今加了image_filter这个已经实现了.但我不知道怎么样才干訪问我上传的原图& ...
- Java正則表達式入门
众所周知,在程序开发中,难免会遇到须要匹配.查找.替换.推断字符串的情况发生,而这些情况有时又比較复杂,假设用纯编码方式解决,往往会浪费程序猿的时间及精力.因此,学习及使用正則表達式,便成了解决这一 ...
- Android 获取手机SIM资料详解
TelephonyManager类主要提供了一系列用于访问与手机通讯相关的状态和信息的get方法.其中包括手机SIM的状态和信息.电信网络的状态及手机用户的信息.在应用程序中可以使用这些get方法获取 ...
- 删除vector中的偶数元素,删除list中的奇数元素
#include<vector> #include<list> #include<iostream> using namespace std; int main() ...
- js倒计时功能
<input id="countdown" type="text" value="140时50分20秒"> <script ...
- 如何强化 TCP/IP 堆栈
TCP/IP 是一种本质上不安全的协议.但是,Windows 2000 实现可以使您配置其操作以防止网络的拒绝服务攻击.默认情况下,本文中所涉及的一些项和值可能并不存在.在这些情况下,请创建该项.值或 ...
- C语言---字符
1.三元符(三字母词):由三个字符组合起来代表其他字符,三元符可以在没有一些字符时使用 ??( [ ??) ] ??! | ??< { ??> } ??' ^ ??= # ??/ \ ?? ...
- VSPackge插件系列:常用IDE功能的封装
继上一篇VSPackge插件系列简单介绍如何正确的获取DTE之后,就一直没发VSPackge插件系列的文章了,最近同事也想了解如何在代码中与VS交互,特发一篇文章示例一些简单功能是如何调用,也以备以后 ...