Java理论与实践:哈希[Java编程]
本文“Java理论与实践:哈希[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
每个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() 必须一致 -- 它们 的后果在随后的调用中将是相同的,假定“不改变对象相等性对比中利用的任何 信息.”这听起来象“计算的后果将不改变,除非实际情形如此.”这一模糊声 明普通注释为相等性和散列值计算应是对象的可肯定性功效,而不是别的.
以上是“Java理论与实践:哈希[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |