Java在重写的equals方法中混淆了==

时间:2014-01-16 06:45:21

标签: java generic-collections

这是我在SCJP书中使用的一段代码。 我理解==比较对象的内存位置以找到相等性.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;
        }
    }

4 个答案:

答案 0 :(得分:1)

"a"字符串文字被实习。每个"a"在内存中都是相同的字符串,因此它们与==相等。请注意,您通常不能依赖于此字符串。如果您执行了以下操作:

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

字符串将被视为彼此!=

答案 1 :(得分:1)

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

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

编辑:

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

答案 2 :(得分:1)

你是对的==比较引用是否指向同一个对象。因此,即使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");

会导致等式评估为false。更具体的例子如下:

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等结构中用作知道存储对象的“存储桶”的值。

答案 3 :(得分:0)

  

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

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

  

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

是的,你已经说过了。

  

如果确实如此,则应该是假的。但它返回真实。 ==如何在这里工作?

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