首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

有效跟正确定义hashCode()和equals()

2012-09-18 
有效和正确定义hashCode()和equals()hashCode方法的作用:总的来说,Java中的集合(Collection)有两类,一类是

有效和正确定义hashCode()和equals()

hashCode方法的作用:

总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set。?
你知道它们的区别吗?前者集合内的元素是有序的,元素可以重复;后者元素无序,但元素不可重复。?
那么这里就有一个比较严重的问题了:要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢??
这就是Object.equals方法了。但是,如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。?
也就是说,如果集合中现在已经有1000个元素,那么第1001个元素加入集合时,它就要调用1000次equals方法。这显然会大大降低效率。????
于是,Java采用了哈希表的原理。哈希(Hash)实际上是个人名,由于他提出一哈希算法的概念,所以就以他的名字命名了。?
哈希算法也称为散列算法,是将数据依特定算法直接指定到一个地址上。如果详细讲解哈希算法,那需要更多的文章篇幅,我在这里就不介绍了。?
初学者可以这样理解,hashCode方法实际上返回的就是对象存储的物理地址(实际可能并不是)。???
这样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。?
如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,?
就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。?

所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。 ???

?

每个Java对象都有?hashCode()?和?equals()?方法,因为这两个方法是在Object类里面定义的。

?

  public int hashCode() {     int hash = 1;    hash = hash * 31 + someNonNullField.hashCode();    hash = hash * 31                 + (someOtherField == null ? 0 : someOtherField.hashCode());    return hash;  }


注意:这两种实施都降低了类状态字段的?equals()?或?hashCode()?方法一定比例的计算能力。根据您使用的类,您可能希望降低superclass的?equals()?或?hashCode()?功能一部分计算能力。对于原始字段来说,在相关的封装类中有helper功能,可以帮助创建散列值,如?Float.floatToIntBits?。

编写一个完美的?equals()?方法是不现实的。通常,当扩展一个自身 Override 了?equals()?的instantiable类时,Override?equals()?是不切实际的,而且编写将被 Override 的?equals()?方法(如在抽象类中)不同于为具体类编写?equals()?方法。关于实例以及说明的更详细信息请参阅?Effective Java Programming Language Guide, Item 7 (?参考资料) 。

热点排行