【问题标题】:Equals() of two String objects are true, but their hashCode() is returning false两个 String 对象的 Equals() 为真,但它们的 hashCode() 返回假
【发布时间】:2015-03-30 18:40:22
【问题描述】:

一个关于String的小程序

    String str1 = new String("Hello");
    String str2 = "Hello";
    System.out.println("=======================");
    System.out.println("Srtr1 == Str2 :: "  + (str1 == str2));
    System.out.println("Srtr1.equals(Str2) :: " + str1.equals(str2));

输出: SRTR1 == STR2 :: 假 srtr1.equals(Str2) :: true

现在怎么可能?众所周知,如果两个对象的equals()为真,那么两个对象的HashCode()一定为真。但是如果 HashCode() 为真,那么 Equals() 可能为真,也可能不为真。

但是在上面的程序中,我们看到,两个String对象的equals()都是true,但是它们的hashCode()返回的是false。

为什么会这样???

【问题讨论】:

    标签: string equals hashcode


    【解决方案1】:

    你根本没有比较 hashCode()s。你在比较平等和身份。

    两个字符串的标识不同,因为您已经看到为每个字符串分配了新对象。身份比较 '==' 返回 false。

    两个String的值相同,所以equals()方法返回true。

    【讨论】:

    • 我理解 System.out.println("Srtr1 == Str2 :: " + (str1 == str2));将检查两个字符串对象的身份。现在我想知道这个'=='运算符在内部做什么?它将根据哪个标准比较两个对象并返回 true/false ?
    • 对于 Java 原语,== 运算符仅比较值(原语没有任何与其值分开的标识)。对于引用类型(例如对象和数组对象)。 == 运算符仅比较身份。身份可以解释为“内存地址”。如果两个对象引用指向内存中的相同物理地址,则称它们是相同的。因此,对象可能具有不同的身份(存储地址),但仍然包含相同的值。相同的对象总是具有相同的值。
    【解决方案2】:

    == 运算符将验证指向每个 String 的指针是否指向同一个对象,在这种情况下它们不是。这与对象的 hashCode() 非常不同,后者返回该对象内数据的整数散列。要验证这一点,您应该替换

    System.out.println("Srtr1 == Str2 :: "  + (str1 == str2));
    

    通过

    System.out.println("Srtr1.hashCode() == Str2.hashCode() :: "
    + (str1.hashCode() == str2.hashCode()));
    

    这将证明你的两个字符串的 hashCode 确实相等:)

    【讨论】:

    • 我理解 System.out.println("Srtr1 == Str2 :: " + (str1 == str2));将检查两个字符串对象的身份。现在我想知道这个'=='运算符在内部做什么?它将根据哪个标准比较两个对象并返回 true/false ?
    • 它检查引用(str1 和 str2)是否指向内存中的同一个对象。在上述情况下,您有两个字符串,都代表“你好”,因此它们彼此是 .equals(),但由于它们是内存中的两个对象 == 将给出错误。您创建了两个 String 对象,但它们恰好代表同一个单词。有关详细信息,请参阅stackoverflow.com/questions/7520432/java-vs-equals-confusion
    • 我明白你的意思是因为我创建了两个 String 对象,但是它们的内存位置不同,那么只有我得到“==”为 False。现在我想知道它正在检查哪个内存地址,引用堆栈中的内存地址或堆中的字符串对象内存地址???还有一个疑问,那么 hashCode() 为任何对象返回什么,比如 Strings 对象? IS hashCode() 返回对象的内存地址?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2010-11-09
    • 1970-01-01
    • 2014-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多