黑马程序员技术交流社区

标题: 有关于hasnCode的问题<已解决> [打印本页]

作者: 刘学    时间: 2012-8-9 10:17
标题: 有关于hasnCode的问题<已解决>
本帖最后由 刘学 于 2012-8-9 12:45 编辑

public class A {
    public static void main(String[] args){
           String str1 = new String("qqqq");
           String str2 = new String("qqqq");
           System.out.println("str1 hashcode = "+str1.hashCode());
           System.out.println("str2 hashcode = "+str2.hashCode());
           System.out.println("str1.equals(str2) = "+str1.equals(str2));
           System.out.println("str1==str2 = "+(str1==str2));

    }
}

输出结果为:
hashcode str1 :  3478592
hashcode str2 :  3478592
str1.equals(str2) : true
str1==str2 : false

请问为什么new出得两个对象hashcode会相等?还有为什么hashcode相等了str1==str2 还输出false?
这是我在网上看到的有些不明白。



作者: 武鹏玉    时间: 2012-8-9 10:29
在java中  equals比较的是两个对象的内容  == 比较的是两个对象的地址

作者: 郑小杰    时间: 2012-8-9 11:04
如果x和y是两个不同的对象,x.hashCode()与y.hashCode()基本上不会相同。举个例子,String类的对象的hashcode是这样计算出来的:
String x;//定义某个String对象。
int hash=0;
for(int i=0;i<x.length();i++)
hash=31*hash+charAt(i);
其hashcode就是该对象在内存中的存储位置

不过看了一下API,上边说,如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。我的理解是这两个对象内容相同,地址还是不同的
作者: 杜鹏云    时间: 2012-8-9 11:05
Object类中的hashCode是返回对象在内存中地址转换成的一个int值(可以就当做地址看)。所以如果没有重写hashCode方法,任何对象的hashCode都是不相等的.
注意的是String、Integer、Boolean、Double等这些类都重写了equals和hashCode方法,这两个方法是根据对象的内容来比较和计算hashCode的.字符串的hash值是根据字符串的值计算的,相同值的字符串对象hash值一定相同,具体的计算方法在jdk的文档中有描述.

作者: 张雪磊    时间: 2012-8-9 11:15
本帖最后由 张雪磊 于 2012-8-9 11:23 编辑

public class A {
    public static void main(String[] args){
           String str1 = new String("qqqq");
           String str2 = new String("qqqq");
         
           /*String hashCode比较的是数据hash值的地址hash地址值,在String类中对Object的hashCode进行
                 了复写,他的计算公式为:
                 String 对象的哈希码按下列公式计算:
           s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
                             使用 int 算法,这里 s
是字符串的第 i 个字符,n 是字符串的长度,^ 表示求幂。
                              (空字符串的哈希码为 0。)
                               所以只要字符全里的字符全相同,那他们的hashCode就相同
                    
                    
                            关于为什么hashcode相等了str1==str2 还输出false?

                             如果你改成下面红色部分就OK了,老师说过,String str2 = new String("qqqq");
                            那是因为“==”比较的是两个引用是否相同,你一个str1,一个str2,引用的是两个对象当然不同了
                  
                   实际上有两个对象
           */

           System.out.println("str1 hashcode = "+str1.hashCode());
           System.out.println("str2 hashcode = "+str2.hashCode());
           System.out.println("str1.equals(str2) = "+str1.equals(str2));
           System.out.println("str1==str2 = "+(str1==str2));
           System.out.println("str1==str2 = "+(str1==str2));      
           
           String str3 = "11111";
           String str4 = "11111";
           System.out.println("str3==str3 = "+(str3==str3));  


    }
}

作者: 武鹏玉    时间: 2012-8-9 11:16
equals()相等的两个对象,hashcode()一定相等;
equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。换句话说,equals()方法不相等的两个对象,hashcode()有可能相等。(我的理解是由于哈希码在生成的时候产生冲突造成的)。
那么:hashcode()不等,一定能推出equals()也不等;hashcode()相等,equals()可能相等,也可能不等。解释下第3点的使用范围,我的理解是在object、String等类中都能使用。在object类中,hashcode()方法是本地方法,返回的是对象的地址值,而object类中的equals()方法比较的也是两个对象的地址值,如果equals()相等,说明两个对象地址值也相等,当然hashcode()也就相等了;在String类中,equals()返回的是两个对象内容的比较,当两个对象内容相等时,
Hashcode()方法根据String类的重写,也可知道hashcode()返回结果也会相等。以此类推,可以知道Integer、Double等封装类中经过重写的equals()和hashcode()方法也同样适合于这个原则。当然没有经过重写的类,在继承了object类的equals()和hashcode()方法后,也会遵守这个原则。

作者: 刘学    时间: 2012-8-9 12:40
谢谢大家的回答,问题已解决了!!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2