【问题标题】:Java confused about == in the overridden equals method [duplicate]Java对重写的equals方法中的==感到困惑[重复]
【发布时间】:2014-01-16 06:45:21
【问题描述】:

这是我在 SCJP 书中使用的一段代码。 我知道 == 比较对象的内存位置以找到相等性,而 .equals 比较哈希码以确定相等性。

我的问题在下面的 sn-p 中,在我们比较的覆盖的 equals 方法中:

(((Moof)o).getMoofValue()) == this.getMoofValue()

在上面的代码中,== 是否比较了字符串值的内存位置?如果是这样,那么它应该是错误的。但它返回真。 == 在这里是如何工作的?

public class EqualsTest {

    public static void main(String args[]){
        Moof one = new Moof("a");
        Moof two = new Moof("a");
        if(one.equals(two)){
            System.out.println("Equal");
        }
        else{
            System.out.println("Not Equal");
        }
    }
}



    public class Moof {
        private String moofValue;
        public Moof(String i){
            this.moofValue = i;
        }
        public String getMoofValue(){
            return this.moofValue;
        }
        public boolean equals(Object o){
            if((o instanceof Moof) && (((Moof)o).getMoofValue()) == this.getMoofValue()){
                return true;
            }
            return false;
        }
    }

【问题讨论】:

  • 对于基元“==”比较“他们的价值”对于非基元“==”比较引用...在这里,您将 2 个字符串与“==”进行比较,所以基本上你是比较引用.. BTW equals() 默认比较引用...它不比较 hashCode。
  • equals() 不会“比较哈希码”......它会比较任何方法编写的比较。
  • ".equals 比较哈希码以确定相等性" - 看到一个这样做的类我会感到非常惊讶。即使在极少数情况下它确实有效,它也不会有效。
  • 除此之外,您发布的代码损坏,因为它没有正确比较Strings。它使用== 比较参考值
  • 感谢您的快速回复。但是 String 不是原始的。这就是我在上面的代码中比较的。

标签: java generic-collections


【解决方案1】:
(Moof)o).getMoofValue()) == this.getMoofValue()) 

这里..您仍在比较对字符串池中相同字符串对象的引用。因为字符串文字是自动实习的。

编辑:

public class TestClass {

    String s;

    TestClass(String s) {
        this.s = s;
    }

    public static void main(String[] args) {

        String s1 = new String("a");
        String s2 = new String("a");
        System.out.println(s1 == s2);

        TestClass t1 = new TestClass("a");
        TestClass t2 = new TestClass("a"); 
        System.out.println(t1 == t2);      // here you are comparing t1 with t2, not t1.s with t2.s so you get false... 
        System.out.println(t1.s == t2.s); // t1.s and t2.s refer to the same "a", so you get true.

     TestClass t3 = new TestClass(s1);
     TestClass t4 = new TestClass(s2);
     System.out.println(t3.s == t4.s);      // false because s1 and s2 are 2 different references. 
    }

}
O/P : 
false
false
true
false

【讨论】:

  • 您好,感谢您的回复。所以我的理解是 == 比较原始和字符串文字的值,但对于对象它比较参考值。如果我错了,请纠正我。
  • @Arun == 检查字符串是否相同(就像其他对象一样)。但是,规范说字符串文字必须引用同一个对象。所以 "a" == "a" 的计算结果为真,而 "a" == new String("a") 的计算结果为假。
  • ==只做一件事;它比较两个值。在原语的情况下,它比较原语值。在对象引用的情况下,它比较引用值。字符串不是特殊的。
  • @Arun-“字符串文字”也是对象。它们被放置在内存中的一个单独位置,称为字符串池,它是堆的一部分......对于字符串也是如此,“==”检查引用,而不是值......
【解决方案2】:

"a" 字符串字面量已被保留。每个"a" 在内存中都是同一个字符串,因此它们与== 比较相等。请注意,一般情况下,您不能依赖此字符串。如果您执行了以下操作:

    Moof two = new Moof("aa".substring(1));

字符串将被视为!=

【讨论】:

    【解决方案3】:

    你是对的,== 比较引用是否指向同一个对象。因此,即使 equals() 的计算结果为 true,两个不同的对象也会使用 == 计算结果为 false。

    以下代码

    (((Moof)o).getMoofValue()) == this.getMoofValue()
    

    检查对象是否相同。但是,在 Java 中,编译时已知的两个相等的字符串常量必须引用相同的字符串对象。看着

    Moof one = new Moof("a");
    Moof two = new Moof("a");
    

    我们可以这样看待

    String theValue = "a";
    Moof one = new Moof(theValue);
    Moof two = new Moof(theValue);
    

    但是,创建一个新的字符串必须返回一个新的对象,所以你可以尝试

    Moof one = new Moof(new String("a"));
    Moof two = new Moof(new String)"a");
    

    这将导致相等性评估为假。更具体的例子如下:

    String a1 = "a";
    String a2 = "a";
    String a3 = new String("a");
    System.out.println(a1 == a2); // true
    System.out.println(a1 == a3); // false
    

    Equals 通常不使用 hashCode 来检查是否相等,但它可以用于快速检查是否需要更多比较。 hashCode 是对象的数字指示符,如果你实现了 PersonId 类,它可以是国家电话前缀和人的年龄的数值。所以一个来自瑞典的 27 岁的人会得到哈希码 4627。现在,当检查两个 PersonId 是否指的是同一个人时,你可能需要做很多比较,但如果 hashCode 不一样,则不需要更多的比较(因为国家或年龄不同,PersonIds 必须指代不同的人)。

    hashCode 用于 HashMap 等结构中,作为一个值,用于了解将对象存储在哪个“桶”中。

    【讨论】:

    • 感谢罗杰的回复。我现在明白了。感谢您的帮助。
    【解决方案4】:

    我知道 == 比较对象的内存位置以找到相等性,而 .equals 比较哈希码以确定相等性。

    不,它没有。 .equals() 做任何写它的人写的东西。在Object.equals(), 的情况下它返回==. 的结果hashCode() 与它无关。

    在上面的代码中,==是不是比较了字符串值的内存位置?

    是的,你已经说过了。

    如果是,那么它应该是错误的。但它返回真。 == 在这里是如何工作的?

    因为"a" 的两次出现都汇集到相同的值,具有相同的地址。

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 1970-01-01
      • 2015-02-11
      • 1970-01-01
      • 2021-09-11
      • 2016-02-21
      • 2019-07-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多