第一条 覆盖equals时请遵守通用规定
- 类的每个实例本质上都是一样的
- 不关心类是否提供了“逻辑相等”的测试功能
- 超类已经覆盖了equals,从超类继承过来的行为对于子类也是合适的
- 类是私有的或是包级私有的,可以确定它的equals方法永远不会被调用
- 五大性质
- 自反性
- 对称性
- 传递性
- 一致性
- 非空性
- 扩展
- 里氏替换原则
- 复合优于继承
- 实现高质量equals方法的诀窍
- 使用==操作符检查“参数是否为这个对象的引用”
- 使用instanceof操作符检查“参数是否为正确的类型”
- 把参数转换成正确的类型
- 对于该类中的每个“关键”域,检查参数中的域是否与该对象中对应的域相匹配(域就是属性)
- 当你编写完成了equals方法之后,应该问自己三个问题:它是否是对称的、传递的、一致的?
- 覆盖equals时总要覆盖hashCode
- 不要企图让equals方法过于智能
- 不要将equals声明中的Object对象替换为其他的类型
第二条 覆盖equals时总要覆盖hashCode
在每个覆盖了equals方法的类中,也必须覆盖hashCode方法。原因:导致该类无法结合所有基于散列的集合一起正常运作,例如HashMap、HashSet和Hashtable
实现HASHCODE的约定
- 在应用程序的执行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法都必须始终如一地返回同一整数。在同一个应用程序的多次执行过程中,每次执行所返回的整数可以不一致
- 如果两个对象根据equals方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode方法都必须产生同样的整数结果
- 如果两个对象根据equals方法比较是不相等的,那么调用这两个对象中任意一个对象的hashCode方法,则不一定要产生不同的整数结果。但是程序员应该知道,给不相等的对象产生截然不同的整数结果,有可能提高散列表的性能
第三条 始终要覆盖toString
虽然遵守toString的约定并不像遵守equals和hashCode的约定那么重要,但是,提供好的toString实现可以使类用起来更加舒适。
实现高质量TOSTRING方法的诀窍
- 在实际应用中,toString方法应该返回对象中包含的所有值得关注的信息
- 无论你是否决定指定格式,都应该在文档中明确地表明你的意图
第四条 谨慎地覆盖clone
Cloneable接口的目的是作为对象的一个mixin接口,表明这样的对象允许克隆。
如果你扩展一个实现了Cloneable接口的类,那么你除了实现一个行为良好的clone方法外,没有别的选择。否则,最好提供某些其他的途径来代替对象拷贝(提供一个拷贝构造器或者拷贝工厂),或者干脆不提供这样的功能。
第五条 考虑实现Comparable接口
它是Comparable接口中唯一的方法。compareTo方法不但允许进行简单的等同性比较,而且允许执行顺序比较,除此之外,它与Object的equals方法具有相似的特征,它还是个泛型。类实现了Comparable接口,就表明它的实例具有内在的排序关系。
总结
以上几点都牵扯到了集合内部的数据结构实现算法,需要了解每个结构。