正在加载...
天天加油 - 助您成才
有效和正确定义hashCode()和equals()
内容摘要:原文:http://www-128.ibm.com/developerworks/cn/java/j-jtp05273/ Brian Goetz 首席顾问, Quiotix Corp 2003 年 8 月 11 日 每个Java对象都有 hashCode() 和 e…

原文:http://www-128.ibm.com/developerworks/cn/Java/j-jtp05273/

Brian Goetz

首席顾问, Quiotix Corp

2003 年 8 月 11 日

每个Java对象都有 hashCode() 和 equals() 方法。许多类忽略(Override)这些方法的缺省实施,以在对象实例之间提供更深层次的语义可比性。在 Java理念和实践这一部分,Java开发人员Brian Goetz向您介绍在创建Java类以有效和准确定义 hashCode() 和 equals() 时应遵循的规则和指南。您可以在 讨论论坛与作者和其它读者一同探讨您对本文的看法。(您还可以点击本文顶部或底部的 讨论进入论坛。)

虽然Java语言不直接支持关联数组 -- 可以使用任何对象作为一个索引的数组 -- 但在根 Object 类中使用 hashCode() 方法明确表示期望广泛使用 HashMap (及其前辈 Hashtable )。理想情况下基于散列的容器提供有效插入和有效检索;直接在对象模式中支持散列可以促进基于散列的容器的开发和使用。

定义对象的相等性

Object 类有两种方法来推断对象的标识: equals() 和 hashCode() 。一般来说,如果您忽略了其中一种,您必须同时忽略这两种,因为两者之间有必须维持的至关重要的关系。特殊情况是根据 equals() 方法,如果两个对象是相等的,它们必须有相同的 hashCode() 值(尽管这通常不是真的)。

特定类的 equals() 的语义在Implementer的左侧定义;定义对特定类来说 equals() 意味着什么是其设计工作的一部分。 Object 提供的缺省实施简单引用下面等式:

public boolean equals(Object obj) { return (this == obj); }

在这种缺省实施情况下,只有它们引用真正同一个对象时这两个引用才是相等的。同样, Object 提供的 hashCode() 的缺省实施通过将对象的内存地址对映于一个整数值来生成。由于在某些架构上,地址空间大于 int 值的范围,两个不同的对象有相同的 hashCode() 是可能的。如果您忽略了 hashCode() ,您仍旧可以使用 System.identityHashCode() 方法来接入这类缺省值。

忽略equals() -- 简单实例

缺省情况下, equals() 和 hashCode() 基于标识的实施是合理的,但对于某些类来说,它们希望放宽等式的定义。例如, Integer 类定义 equals() 与下面类似:

public boolean equals(Object obj) {

return (obj instanceof Integer

&& intValue() == ((Integer) obj).intValue());

}

在这个定义中,只有在包含相同的整数值的情况下这两个 Integer 对象是相等的。结合将不可修改的 Integer ,这使得使用 Integer 作为 HashMap 中的关键字是切实可行的。这种基于值的Equal方法可以由Java类库中的所有原始封装类使用,如 Integer 、 Float 、 Character 和 Boolean 以及 String (如果两个 String 对象包含相同顺序的字符,那它们是相等的)。由于这些类都是不可修改的并且可以实施 hashCode() 和 equals() ,它们都可以做为很好的散列关键字。

为什么忽略equals()和hashCode()?

如果 Integer 不忽略 equals() 和 hashCode() 情况又将如何?如果我们从未在 HashMap 或其它基于散列的集合中使用 Integer 作为关键字的话,什么也不会发生。但是,如果我们在 HashMap中 使用这类 Integer 对象作为关键字,我们将不能够可靠地检索相关的值,除非我们在 get() 调用中使用与 put() 调用中极其类似的 Integer 实例。这要求确保在我们的整个程序中,只能使用对应于特定整数值的 Integer 对象的一个实例。不用说,这种方法极不方便而且错误频频。

Object 的interface contract要求如果根据 equals() 两个对象是相等的,那么它们必须有相同的 hashCode() 值。当其识别能力整个包含在 equals() 中时,为什么我们的根对象类需要 hashCode() ? hashCode() 方法纯粹用于提高效率。Java平台设计人员预计到了典型Java应用程序中基于散列的集合类(Collection Class)的重要性--如 Hashtable 、 HashMap 和 HashSet ,并且使用 equals() 与许多对象进行比较在计算方面非常昂贵。使所有Java对象都能够支持 hashCode() 并结合使用基于散列的集合,可以实现有效的存储和检索。

实施equals()和hashCode()的需求

实施 equals() 和 hashCode() 有一些限制, Object 文件中列举出了这些限制。特别是 equals() 方法必须显示以下属性:

Symmetry:两个引用, a 和 b , a.equals(b) if and only if b.equals(a)

Reflexivity:所有非空引用, a.equals(a)

Transitivity:If a.equals(b) and b.equals(c) , then a.equals(c)

Consistency with hashCode() :两个相等的对象必须有相同的 hashCode() 值

Object 的规范中并没有明确要求 equals() 和 hashCode() 必须 一致-- 它们的结果在随后的调用中将是相同的,假设“不改变对象相等性比较中使用的任何信息。”这听起来象“计算的结果将不改变,除非实际情况如此。”这一模糊声明通常解释为相等性和散列值计算应是对象的可确定性功能,而不是其它。

对象

12 3 4 下一页
数据载入中,请稍后……
发表评论
昵 称: 验证码:
评 分:
内 容:
0/1000)

提示:Alt+S快速发表

排行

  1. 用Java编写的记事本程序(1)
  2. Lucene的简单使用
  3. Ant全攻略
  4. Excel导入数据库工具包
  5. Java操作Excel的一种方法
  6. 基于AJAX技术的DataGrid控件编程
  7. 一个封装了基本JDBC操作的类
  8. 我的一个工作流引擎的设计概要(多多指教)
  9. XMLHTTP无刷新自动实时更新数据
  10. Oracle学习快速入门基础教程
  11. 更有效的使用Jbuilder编辑器
  12. 有关汉字编码的一道编程问题
  13. eclipse RCP:Rich Client的新选择
  14. oracle-内存表
  15. J2ME入门专题系列之三:搭建开发环境
  16. Conditional Compilation In Java @ JDJ
  1. 对《Java与模式》中工厂方法模式的异议
  2. DAO编程模式
  3. 优化Apache 2.0 性能
  4. java连接常见数据库的连接字符串
  5. J2ME入门专题系列之三:搭建开发环境
  6. Learn Spring in spring(三)
  7. 实现JAVA手动布局中各个组件能随窗口变化的
  8. Lucene的简单使用
  9. 用Java编写的记事本程序(1)
  10. 用Delphi开发JNI应用
  11. Ant全攻略
  12. 利用iText写PDF心得
  13. Java发展展望
  14. 用Eclipse进行可视化Java界面设计
  15. 在Eclipse中使用ANT灵活构建Web应用
  16. 字体类Font的使用
  1. Excel导入数据库工具包
  2. 有效和正确定义hashCode()和equals()
  3. 字体类Font的使用
  4. VisualAge for Java 2.0 @ JDJ
  5. 实现JAVA手动布局中各个组件能随窗口变化的
  6. java对象序列化学习笔记
  7. Lucene的简单使用
  8. 我的一个工作流引擎的设计概要(多多指教)
  9. 更有效的使用Jbuilder编辑器
  10. 用Java编写的记事本程序(1)
  11. Eclipse vs NetBeans:两款一流的JAVA开源I
  12. 有关汉字编码的一道编程问题
  13. 用Eclipse进行可视化Java界面设计
  14. ant 使用
  15. Ant全攻略
  16. 学习心得:Java基本功??Reference

最近更新

  • 推荐阅读
  • 关于我们 | 版权申明 | 广告服务 | 友情链接 | 网站地图 | 使用帮助 | ©2006-2009 天天加油 TTADD.COM