第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接口唯 ...
随机推荐
- SQLite 使用教程2 语法
http://www.runoob.com/sqlite/sqlite-syntax.html SQLite 语法 SQLite 是遵循一套独特的称为语法的规则和准则.本教程列出了所有基本的 SQLi ...
- 软件测试之WEB测试经典总结
在Web工程过程中,基于Web系统的测试.确认和验收是一项重要而富有挑战性的工作.基于Web的系统测试与传统的软件测试不同,它不但需要检查和验证是否按照设计的要求运行,而且还要测试系统在不同用户的浏览 ...
- Redis实战之征服 Redis + Jedis + Spring (一)
Redis + Jedis + Spring (一)—— 配置&常规操作(GET SET DEL)接着需要快速的调研下基于Spring框架下的Redis操作. 相关链接: Redis实战 Re ...
- Config the Android 5.0 Build Environment
In this document Choosing a Branch Setting up a Linux build environment Installing the JDK ...
- java_spring_List,Map,Properties,Set注入与遍历
package com.dao.bean.www; import java.util.List; import java.util.Map; import java.util.Properties; ...
- iOS开发技巧系列---使用链式编程和Block来实现UIAlertView
UIAlertView是iOS开发过程中最常用的控件之一,是提醒用户做出选择最主要的工具.在iOS8及后来的系统中,苹果更推荐使用UIAlertController来代替UIAlertView.所以本 ...
- C# 之 服务端获取远程资源
获取指定网页的远程资源可使用 WebClient.WebRequest.HttpWebRequest 三种方式来实现.当然也可使用webBrowse,webBrowse不做介绍. 通过 System. ...
- 谈谈MSP430 的框架程序
最近在学习MSP430f149这块单片机,开始程序也没烧进去,弄了一天,发现串口不能下载,买了个jtag下载器,才搞定.现在也谈谈开始写程序的一些方法吧 程序重要的是框架,有这个基础之后才能行云流水的 ...
- 分布式算法(一致性Hash算法)
一.分布式算法 在做服务器负载均衡时候可供选择的负载均衡的算法有很多,包括: 轮循算法(Round Robin).哈希算法(HASH).最少连接算法(Least Connection).响应速度算法( ...
- 蓝牙 GameKit
一.准备工作 1.搭建UI 2.拖线 // 图片 @property (weak, nonatomic) IBOutlet UIImageView *imageView; // 建立连接 - (IB ...