A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 光sail 中级黑马   /  2012-4-18 22:04  /  4707 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 光sail 于 2012-4-18 22:06 编辑

Object类的HashCode方法返回该类的对象的哈希码值,该对象的值什么时候相同,什么时候不同?
同一个对象的hashCode 方法的多次调用,他们应该返回值一样么?
对于两个对象来说,如果使用equals 方法比较返回true,那么这两个对象的hashCode值一定是相同么?
对于两个对象来说,如果使用equals 方法比较返回false,那么这两个对象的hashCode值相同么?
对于Object类来说,不同的Object 对象的hashCode值是相同么?

4 个回复

倒序浏览
equals(Object obj)和hashCode()方法,使相同内容的对象其equals(Object obj)为真,返回的hashCode()一致。
回复 使用道具 举报
hashCode 的常规协定是:

在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)

回复 使用道具 举报
hashCode()是用来产生哈希玛的,而哈希玛是用来在散列存储结构中确定对象的存储地址的,(这一段在   Java编程思想   中讲的很清楚的)象util包中的   带   hash   的集合类都是用这种存储结构   :HashMap,HashSet,   他们在将对象存储时(严格说是对象引用),需要确定他们的地址吧,   而HashCode()就是这个用途的,一般都需要重新定义它的,因为默认情况下,由   Object   类定义的   hashCode   方法会针对不同的对象返回不同的整数,这一般是通过将该对象的内部地址转换成一个整数来实现的,现在举个例子来说,   就拿HashSet来说   ,在将对象存入其中时,通过被存入对象的   hashCode()   来确定对象在   HashSet   中的存储地址,通过equals()来确定存入的对象是否重复,hashCode()   ,equals()都需要自己重新定义,因为hashCode()默认前面已经说啦,而equals()   默认是比较的对象引用,你现在想一下,如果你不定义equals()的话,那么同一个类产生的两个内容完全相同的对象都可以存入Set,因为他们是通过equals()来确定的,这样就使得HashSet   失去了他的意义.
回复 使用道具 举报
我们应该先了解java判断两个对象是否相等的规则。
在java的集合中,判断两个对象是否相等的规则是:
首先,判断两个对象的hashCode是否相等
如果不相等,认为两个对象也不相等
如果相等,则判断两个对象用equals运算是否相等
在我们往HashSet中添加自定义对象的时候(HashSet中不能添加相同的对象),HashSet会先将已存在的对象与欲添加的对象进行一一对比,相同的对象不允许再添加。其比较规则为:如果两对象的hashCode()方法返回值不一样,肯定不是相同的对象,可添加;如果 hashCode()一样,则再判断equals()返回是否为真,不为真则肯定不是相同的对象,可添加,为真由证明两对象完全相同,不再添加到 HashSet中。那按Object()中的hashCode()方法,则只要内存不一样,则两对象的hashCode就不一样,则认为两对象不相同,可往HashSet中添加,这违背了我们实际需求。

    结论:我们自定义类如果想往HashSet等集合中添加时,必须重写equals(Object obj)和hashCode()方法,使相同内容的对象其equals(Object obj)为真,返回的hashCode()一致。如下:
重写equals()方法
下面给出编写一个完美的equals方法的建议:
1) 显式参数命名为otherObject,稍后需要将它转换成另一个叫
做 other的变量。
2) 检测this与otherObject是否引用同一个对象:
        if (this == otherObject) return true;
        这条语句只是一个优化。实际上,这是一种经常采用的形
        式。因为计算这个等式要比一个一个地比较类中的域所付
        出的代价小得多。
3) 检测otherObject是否为null,如果为null,返回false。这项
      检测是很必要的。
                if (otherObject == null) return false;
      比较this与otherObject是否属于同一个类。如果equals的语
      义在每个子类中有所改变,就使用getClass检测:
              if (getClass() != otherObject.getClass()) return false;
      如果所有的子类都拥有统一的语义,就使用instanceof检测:
              if (! (otherObject instanceof ClassName)) retrun false;
4)将otherObject转换为相应的类类型变量:
        ClassName other = (ClassName)otherObject;
5) 现在开始对所有需要比较的域进行比较了。使用 == 比较
      基本类型域,使用equals比较对象域。如果所有的域都匹
      配,就返回ture;否则返回false。
如果不相等,认为两个对象也不相等
如果相等,认为两个对象相等
我们在equals方法中需要向下转型,效率很低,所以先判断hashCode方法可以提高效率

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马