Pregunta

This is the piece of code I used from the SCJP book. I understand that == compares the memory location of the objects to find the equality and .equals compares the hashcode to determine the equality.

My question is in the below snippet, in the overrided equals method we compare :

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

in the above code, does the == compare the memory location of the string value? If it does then it should be false. But it returns true. How does the == work here?

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;
        }
    }
¿Fue útil?

Solución

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

here..You are still comparing references to the same String object in the String pool. Because String literals are interned automatically.

Edit :

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

Otros consejos

The "a" string literals are interned. Each "a" is the same string in memory, so they compare equal with ==. Note that you can't rely on this for strings in general. If you did the following:

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

the strings would be considered != to each other.

You are right that == compares if the references point to the same object. So, two different objects would evaluate to false with == even if equals() would evaluate to true.

S the following code

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

checks if the objects are the same. However, in Java two equal string constants that are known at compile time must reference the same string object. Looking at

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

We could view this as

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

However, making a new string must return a new object so you can try

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

which would cause the equality to evaluate to false. More specific example below:

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

Equals does normally not use hashCode to check for equality but it could be used to make a quick check if more comparisons are needed. The hashCode is a numerical indicator of the object, which if you implemented a PersonId class could be a numerical value of the country phone prefix and age of the person. So a 27 year old person from Sweden would get hash code 4627. Now, when checking if two PersonId refers to the same person you might have to do a lot of comparisons, but if the hashCode is not the same then no more comparisons are needed (since either the country or age is different and the PersonIds must refer to different persons).

The hashCode is used in structures such as HashMap as a value for knowing which "bucket" to store the object in.

I understand that == compares the memory location of the objects to find the equality and .equals compares the hashcode to determine the equality.

No it doesn't. .equals() does whatever the guy who wrote it wrote. In the case of Object.equals(), it returns the result of ==. hashCode() has nothing to do with it.

in the above code, does the == compare the memory location of the string value?

Yes, you've already said that.

If it does then it should be false. But it returns true. How does the == work here?

Because both occurrences of "a" are pooled to the same value, with the same address.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top