effective java读书笔记六

来源:互联网 发布:ubuntu 删除 硬盘 编辑:程序博客网 时间:2024/05/14 19:06
第11条:考虑实现Comparable接口


1、Java平台库库的所有值类(value classes)都实现了 Comparable接口。比较某对象与另指定对象的顺序。当这个物件小于、等于、大于 指定对象时,分别传回负整数、0、正整数。如果指定对象的型别不允许与这个对象进行比较,就抛出ClassCastException异常。 
2、运用 compareTo()所做的相等性测试必须遵守equals()所遵守的切约束:反身性、对称性、递移性和有效性。所以 equals() 的告诫同样适用于此:对于个可实体化(instantiable)class,并不存在个「既 可增加新外观(aspect)以扩展 class、又能维持 compareTo()契约」的办法(条 款 7)。equals()的迂回解法在此也同样适用:如果你打算对个实现了 Comparable 的 class 增加个有意义的外观(aspect),请不要扩展(继承)这个 class,而是另写个 class,其有个字段包含这个 class(译注:亦即不使用继承, 改用复合),然后提供个返回该字段的 "view"(映像)函式。这种方法使你得 以自由实现第个 class 的 compareTo(),同时允许其客户必要时将第个 class 的实体视为第个class的实体。
如果compareTo的相等性测试与equals的相等性测试不一致的时候可能出现问题,
例如:BigDecimal类,它的compareTo()与equals()不一致。如果 你创建个 HashSet,然后为它添加新元素 new BigDecimal(-0.0f)和 new BigDecimal(0.0f),这个 set 将含有 2 个元素,这是因为以 equals()比较述两个 BigDecimal 元素,结果并不相等(译注:因此得以都被放入「元素不得重复」的 set )。如果改用 TreeSet 而不是 HashSet,进行同样过程,将只含有1个元素,因为透过compareTo()比较两个BigDecimal,结果相等


测试例子:

import java.util.ArrayList;import java.util.List;public class TestCompare {static class Person implements java.lang.Comparable<Person> {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic int compareTo(Person person) {String _name = person.getName();int _age = person.getAge();if (_age == age) {return name.compareTo(_name);}return _age - age;}@Overridepublic String toString() {return "name=" + name + "\tage=" + age;}}public static void main(String[] args) {List<Person> persons = new ArrayList<Person>();persons.add(new Person("zhangs", 21));persons.add(new Person("zhangs", 24));persons.add(new Person("lisi", 21));persons.add(new Person("wanwu", 21));persons.add(new Person("zhangs1", 21));java.util.Collections.sort(persons);for (Person person : persons) {System.out.println(person);}}}


原创粉丝点击