Java理论与实践:哈希 - 编程入门网
方面非常昂贵。使所有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() 必须一致 -- 它们 的结果在随后的调用中将是相同的,假设“不改变对象相等性比较中使用的任何 信息。”这听起来象“计算的结果将不改变,除非实际情况如此。”这一模糊声 明通常解释为相等性和散列值计算应是对象的可确定性功能,而不是其它。 Java理论与实践:哈希(2)时间:2010-12-20 IBM Brian Goetz对象相等性意味着什么? 人们很容易满足Object类规范对equals() 和 hashCode() 的要求。决定是否 和如何忽略equals()除了判断以外,还要求其它。在简单的不可修值类中,如 Integer(事实上是几乎所有不可修改的类),选择相当明显 -- 相等性应基于基 本对象状态的相等性。在Integer情况下,对象的唯一状态是基本的整数值。 对于可修改对象来说,答案并不总是如此清楚。equals() 和hashCode() 是 否应基于对象的标识(象缺省实施)或对象的状态(象Integer和String)?没有简 单的答案 -- 它取决于类的计划使用。对于象List和Map这样的容器来说,人们 对此争论不已。Java类库中的大多数类,包括容器类,错误出现在根据对象状态 来提供equals()和hashCode()实施。 如果对象的hashCode()值可以基于其状态进行更改,那么当使用这类对象作 为基于散列的集合中的关键字时我们必须注意,确保当它们用于作为散列关键字 时,我们并不允许更改它们的状态。所有基于散列的集合假设,当对象的散列值 用于作为集合中的关键字时它不会改变。如果当关键字在集合中时它的散列代码 被更改,那么将产生一些不可预测和容易混淆的结果。实践过程中这通常不是问 题 -- 我们并不经常使用象List这样的可修改对象做为HashMap中的关键字。 一个简单的可修改类的例子是Point,它根据状态来定义equals()和 hashCode()。如果两个Point 对象引用相同的(x, y)座标,Point的散列值来源 于x和y座标值的IEEE 754-bit表示,那么它们是相等的。 对于比较复杂的类来说,equals()和hashCode()的行为可能甚至受到 superclass或interface的影响。例如,List接口要求如果并且只有另一个对象 是List,而且它们有相同顺序的相同的Elements(由Element上的Object.equals () 定义),List对象等于另一个对象。hashCode()的需求更特殊--list的 hashCode()值必须符合以下计算:
不仅仅散列值取决于list的内容,而且还规定了结合各个Element的散列值的 特殊算法。(String类规定类似的算法用于计算String的散列值。) 编写自己的equals()和hashCode()方法 忽略缺省的equals()方法比较简单,但如果不违反对称(Symmetry)或传递 性(Transitivity)需求,忽略已经忽略的equals() 方法极其棘手。当忽略 equals()时,您应该总是在equals()中包括一些Javadoc注释,以帮助那些希望 能够正确扩展您的类的用户。 作为一个简单的例子,考虑以下类:
|
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |