3

I have seen many articles saying that is a reference comparison, i.e. both objects point to the same memory location .equals() evaluates to the comparison of values in the objects.

But I don't understand what this means, because when I tried understanding the following code, the strings printed were "Different" and "Not same". How is that possible? What does .equals mean? Am I understanding this all wrong? I thought the answer would be "Different" and "Same"?

import java.util.Arrays;

public class HelloWorld {

    public static void main(String[] args) {
       int arr1[] = {1, 2, 3};
       int arr2[] = {1, 2, 3};
       if (arr1 == arr2){
           System.out.println("Same");
       } else {
           System.out.println("Different");
       }
       if (arr1.equals(arr2)){
           System.out.println("Same");}
       } else {
           System.out.println("Not same");
       }
    }
}
TylerH
  • 20,799
  • 66
  • 75
  • 101
  • you just started with the wrong data type to understand that... arrays! use another type and for Arrays there is an special way to do that, use the method ***Arrays.equals(a, a2)*** – ΦXocę 웃 Пepeúpa ツ Jun 19 '17 at 06:35
  • Here the explanation http://www.geeksforgeeks.org/compare-two-arrays-java/ – John Joe Jun 19 '17 at 06:35
  • 3
    Arrays do not override equals(), so they inherit the default behavior defined by the Object class, which is that equals() works just as == does. The distinction is only meaningful for classes that override equals(). – yshavit Jun 19 '17 at 06:36
  • 3
    Surely this is a duplicate. – Ryan Leach Jun 19 '17 at 06:40
  • I have someone the answer points but I only get the == part, if .equals is checking the content, how come the code didnt print "same" for the second if : –  Jun 19 '17 at 07:08

4 Answers4

5

Yes, == with objects is a reference comparison* (checks if the operands are references to the same object), while equals is whatever the class involved defines it to mean (within the requirements documented for equals). Some classes define equals as being the same as ==, including Java's arrays. (Because they don't override the default implementation from Object.equals, which uses ==.)

If you want to compare Java arrays based on the equality of their contents, you use Arrays.equals instead.

Your experiment would have worked if you used a class that defined equals in a useful way, you were just unlucky picking arrays. It's a bit tricky to find a class in the JVM to use for this experiment, because so many either don't implement equals (like arrays) or could be confusing because there are several immutable classes which may reuse instances (although not if you explicitly use new; but I don't want to go down a path of having you use new with something you probably shouldn't, like String; more on that here). I'm going to give up on picking a good example and use the slightly old class SimpleDateFormat:

DateFormat a = new SimpleDateFormat("yyyy-MM-dd");
DateFormat b = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(a == b ? "== Same" : "== Different");
System.out.println(a.equals(b) ? "equals Same" : "equals Different");

That outputs

== Different
equals Same

because SimpleDateFormat defines equals to check that the other object is also a SimpleDateFormat with the same formatting.

Live example


Re your comment on the question:

I have someone the answer points but I only get the == part, if .equals is checking the content, how come the code didnt print "same" for the second if

Because equals doesn't, necessarily, check content. It only does if a class overrides the default Object.equals (which just uses ==) and implements a content check. Arrays don't. (One could argue that they should have, but they don't.) Other classes, like SimpleDateFormat and String and Integer and HashMap do.

In essence: == is always a reference comparison. equals may or may not be a contents comparison, depending on what class you're using it on.

So for instance, say we have this class:

class Example1
{
    private int content;

    Example1(int content) {
        this.content = content;
    }

    public static void main (String[] args) throws java.lang.Exception
    {
        Example1 a = new Example1(42);
        Example1 b = new Example1(42);
        System.out.println(a == b ? "== Same" : "== Different");
        System.out.println(a.equals(b) ? "equals Same" : "equals Different");
    }
}

Since that class doesn't override equals, you'll get the same answer ("Different") for both == and equals. Live Example.

But if we override equals to define what it would mean for two instances to be equal (in this case: because they have the same content):

class Example2
{
    private int content;

    Example2(int content) {
        this.content = content;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null || !obj.getClass().equals(this.getClass())) {
            return false;
        }
        Example2 other = (Example2)obj;
        return this.content == other.content;
    }

    @Override
    public int hashCode() {
        return this.content;
    }

    public static void main (String[] args) throws java.lang.Exception
    {
        Example2 a = new Example2(42);
        Example2 b = new Example2(42);
        System.out.println(a == b ? "== Same" : "== Different");
        System.out.println(a.equals(b) ? "equals Same" : "equals Different");
    }
}

Now equals says two instances with the same content are the same, because the class defines what that means. Live Example. (Also note that when overriding equals, you must override hashCode, which is why I've done so above.)


* More generally, == tests if the values of its operands are the same. The value in the case of reference types is an object reference, and two object reference values are only the same when they refer to the same object are are only different when they refer to different objects (or one of them is null; not referring to an object at all).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • I know this is the answer but im still so confused . I get the == part I dont get the .equals however still –  Jun 19 '17 at 07:07
  • @LiveStream: I've added an example and a bit more explanation, hope that helps. – T.J. Crowder Jun 19 '17 at 07:11
  • ok so the equals method only checks if things are equal to each others content right?So how come my array didnt give me a result of it being true. they both contain the same information –  Jun 19 '17 at 07:14
  • @LiveStream: I just added an answer to your comment on the question. – T.J. Crowder Jun 19 '17 at 07:15
  • ok so if im getting this right == is the same as .equals when comparing arrays? –  Jun 19 '17 at 07:17
  • @LiveStream: Right, and when comparing instances of any other class that doesn't override the default implementation of `equals` it inherits from `Object`. The assumption in Java is that two instances cannot meaningfully be `equals` to one another unless a class explicitly defines what exactly that means, and for whatever reason, when defining arrays, they decided not to have arrays define `equals`. I've added a couple of further examples to demonstrate that. – T.J. Crowder Jun 19 '17 at 07:27
0

To create object you need some portion of memory to store it.

Operator == checks if two variables point to the same memory block. That is they points to the same object instance (they are one person under different aliases).

equals() is a method and checks equality by some algorithm. Meaning two object contain the same data (they are different persons but with the same face, twins for example). Default implementation for java.lang.Object#equals is

public boolean equals(Object obj) {
    return (this == obj);
}

Using you IDE you can ensure that equals for an array is actually java.lang.Object#equals. To check two arrays for equality you should use Arrays.equals. It has also a lot of other useful methods for manipulating with arrays. It is a good idea to check this class first when you need to do something with an array. It saves much time and code lines.

EDITED

Arrays (int[], float[], String[], AnyClass[]) does not implement custom equals method. So for array and for any your custom class equals() and == do same operation unless you override equals() and provide custom comparison. Like

public class Person {
    public String name;
    public String surname;

    public Person(String name, String surname) {
        this.name = name;
        this.surname = surname;
    }

    public boolean equals(Object thatObj) {
        if (thatObj instanceof Person) {
            Person that = (Person) thatObj;
            return this.name.equals(that.name) &&
                this.surname.equals(that.surname);
        }
        return false;
    }
}
invenit
  • 424
  • 4
  • 11
  • ok if equals checks the equality of the data how come there not .equals? why is that false. im so confused –  Jun 19 '17 at 07:10
  • @LiveStream, `equals` for arrays (for your case) is default implementation of the method. It actually do the same as `==` operator. Check code snippet from my answer - `return (this == obj)`. If you use any IDE use `Ctrl + Click` on method that confuses you and check how is it implemented. I always do this when doubt. – invenit Jun 19 '17 at 07:20
0

I always use below example to understand the difference between == and .equals,

String s1 = new String( "Test" );
String s2 = new String( "Test" );

System.out.println( s1 == s2 ); // will print 'false'
System.out.println( s1.equals( s2 )); //  will print 'true'

since new keyword always create fresh new objects it will have 2 different references. Therefor, == comparison will return false. This happens because it is comparing the reference value(or someone can say memory location value) only which different. However, If you initialize the same thing like below(auto boxing),

String s1 = "Test";
String s2 = "Test";

System.out.println( s1 == s2 ); // will print 'true'
System.out.println( s1.equals( s2 )); //  will print 'true'

Now s1 and s2 both will use the same object and same reference.

tk_
  • 16,415
  • 8
  • 80
  • 90
-1

the == compare the reference. in your example when you create the variable arr1[] it created in memory and had it own address in the memory so when you create another variable arr2[] it created in memory but with another address so when you compare arr1 address is not equal to arr2 address. but when you use .equal it does not compare the memeory location but instead it compare the value inside. if you want arr1 to arr2 == each other it must be like this :

arr1[] = [1,2,3] arr2[] = arr1;

then arr1 == arr2 //true

Potato
  • 770
  • 1
  • 8
  • 18