`
TonyLian
  • 浏览: 401491 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【第11条】考虑实现Comparable接口

阅读更多

    与本章(前面3条)所讨论的方法不同,compareTo方法在Object中并没有被声明,它是java.lang.Comparable接口中唯一的方法。实现这一接口,也可以说类具有了“内在排序能力”。

   

    compareTo方法除了允许比较相等外,还可以比较大小。通常如果 x < y ,则 x.compareTo(y) 返回一个负整数(通常是 -1);如果 x.equals(y) == true ,则 x.compareTo(y) 返回 0;如果 x > y ,则 x.compareTo(y) 返回一个正整数(通常是 1)

 

    compareTo具有和equals相似的约定:

 1)自反性:x.compareTo(x)一定为true
 2)对称性:当且仅当x.compareTo(y) 为 0;那么y.compareTo(x)也必须为 0
 3)传递性:如果x.compareTo(y) == 0,sgn(x.compareTo(z)) == sgn(y.compareTo(z)) 必须成立 (sgn为取正负返回 -1; 0; 1)

                 如果x.compareTo(y) < 0,y.compareTo(z) < 0;那么x.compareTo(x) 也必须 < 0
 4)一致性:对于任意引用值x和y,如果用于compareTo比较的对象信息没有被修改的话,那么多次调用x.compareTo(y)返回的值是一致的
 5)强力建议:(x.compareTo(y) == 0) == (x.equals(y)),但这并不是严格要求。一般而言,任何实现了Comarable接口的类,若违反了这个条件,应该明确予以说明。推荐这样的说法:“注意:该类具有内在的排序能力,但是与equals不一致。”

 

    一个例子是 BigDecimal ,这是一个没有满足这一条件的类(其实这一条并非真正的规则,仅仅是个建议而已)。我们实例化2个对象:new BigDecimal("1.0") 和 new BigDecimal("1.00"),若把这2个对象放入HashSet中,HashSet将有2个元素,而放入TreeSet,则这个TreeSet中仅有1个元素。原因是,HashSet是依赖hashCode和equals来判断的;而TreeSet是依赖compareTo来判断的。(细节请见BigDecimal的文档)

 

    compareTo的用处除了我们可以直接使用外,很多API已经加以利用了,你只要提供具有内在排序能力(实现了Comparable接口)的对象就可以了,比如上面例子中的TreeSet。再例如,一个数组,如果放入数组的元素都是某个实现了Comparable接口的类的实例的话,那么给这个数组排序就可以简单到一句话:

Arrays.sort(myArray);   // 使用Arrays的sort静态方法,其内部会使用实参的compareTo方法

 

 

【本章回顾】本章讲了作为所有类的超类的Object需要被子类改写的4个方法以及一个compareTo方法。作为最最基本的类——Object,可能也被认为是最最简单的,但是真正能够掌握其真谛的程序员可能并不多。尤其是对于要关心甚至是自己动手写“底层”代码的程序员来说,这一章读上三遍是很值得的。

 

 

 

 

 

【Effective Java 学习笔记】系列连载专题请见:
http://tonylian.iteye.com/categories/64208

 

分享到:
评论

相关推荐

    effecctivejava 第三版中文

    11. **比较对象的正确方式**:实现Comparable接口或使用Comparator接口来比较对象。注意equals()和hashCode()的一致性原则。 12. **优先考虑异常安全的函数**:设计函数时,应尽量避免在正常路径上抛出异常,避免...

    AIC的Java课程1-6章

    第11章 集合 4课时  理解什么是集合以及Java的集合框架。  辨析List,Set和Map接口。 • 理解List接口,辨别使用List接口的实现类。 • 理解Set接口,辨别使用Set接口的实现类。...

    java私塾学习笔记整理

    #### 第十一章:Swing和GUI事件处理 **一、GUI事件监听器接口** 监听器接口定义了事件处理器应实现的方法。 **二、实现方法** 通过实现监听器接口或使用匿名内部类等方式。 **事件适配器**:提供了默认空实现的...

    JavaSE笔试程序题(20180307)

    8. **Person类**:实现Comparable接口,重写compareTo()方法进行对象比较,使用ArrayList存储并调用Collections.sort()排序。 9. **GBK字节数分割字符串**:使用InputStreamReader和BufferedReader读取,计算字节数...

    EFFECT JAVA 中文

    4. **枚举代替常量类**:枚举类型在Java中提供了许多优势,如自动实现Comparable接口,可以添加方法,以及防止实例化。作者推荐使用枚举来替代传统的final常量类。 5. **不可变对象**:不可变对象一旦创建,其状态...

    超级全面的JAVA面试题集

    - 在子类构造器中,`super()` 必须作为第一条语句,用来调用父类的无参构造器。 - `this()` 用于在同一类中调用其他构造器。 2. **作用域 public, protected, private,以及不写时的区别**: - `public`:全局...

    华为java面试题

    - 实现比较通常需要实现`Comparable`接口或`Comparator`接口。 15. **插入法排序的Java代码实现** - 插入排序是一种简单的排序算法,通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应...

    Java面试题经典集合

    - 两者都在构造器中使用,且必须作为第一条语句。 - `super()`和`this()`不能同时出现在同一个构造器中。 2. 作用域`public, protected, private`以及不写时的区别? - `public`: 可以在任何地方访问。 - `...

    JAVA面试题

    为了在集合框架中实现比较,需要实现`Comparable`接口或提供一个实现了`Comparator`接口的对象。 #### 15. 用插入法进行排序代码如下 插入排序是一种简单的排序算法,其实现逻辑是遍历数组并将每个元素插入到已...

    java经典面试

    它必须是子类构造函数的第一条语句。通过这种方式,可以确保在子类构造之前,父类的初始化已经完成。 - **`this()`**: 在同一个类的构造函数之间相互调用时使用`this()`。同样地,`this()`也必须是构造函数的第一条...

    java面试题

    要实现比较功能,可以实现`Comparable`接口或`Comparator`接口。 #### 15. 用插入法进行排序代码 插入排序是一种简单的排序算法,通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并...

    2021-2022计算机二级等级考试试题及答案No.9189.docx

    18. TreeSet集合如果没有指定比较器,需要元素实现Comparable接口以进行排序。 19. 十进制数58转换为二进制是111010。 20. 笛卡尔积操作在关系代数中用于合并两个关系的所有可能配对,而选择操作用于筛选满足特定...

    java sort面试题目

    - 实现`Comparable`接口:这种方式要求被排序的类自身实现比较逻辑。 - 提供`Comparator`对象:这种方式更为灵活,可以在不修改类自身的情况下提供不同的排序规则。 #### 五、不同排序算法的性能对比 - **快速排序...

    向Weka添加自己的算法、core包分析及相关资料

    - 实现`Comparable`接口,方便版本间的比较。 5. **Queue.java**: - 实现了一个基本的队列结构,支持序列化。 - 内部类`QueueNode`作为队列的基本单元。 6. **RandomVariates.java**: - 用于生成各种随机变量...

    Jsp开发遇到的70个问题及解决方法记录

    Comparable接口的使用 - **问题描述**:如何使用`Comparable`接口来进行对象排序。 - **解决方案**:实现`Comparable`接口可以让对象具有比较能力,从而可以直接使用`Arrays.sort()`等排序方法对对象数组进行排序...

Global site tag (gtag.js) - Google Analytics