DailyBuzz / Java

[A Detailed Discussion] Difference between == and .equals() in Java

di-logo-java-orangeBy the title, you might be thinking, it’s a very common topic in Java and there are lots of threads on this. What’s new about this article? hmm…well, I have summerized the concepts of using == and .equals() for wrapper class, user-defined class and mentioned about some queries which will make you know Java better. Lets start…

Abstract concept:  (You must have knew it)

equals()  method is to determine whether two instances of a given class are “meaningfully equivalent” and the operator, ==, tests to see if two object reference variables refer to the exact same instance of an object.

Case-1:

        Integer m = new Integer(10);
        Integer n = new Integer(10);
        if (m.equals(n))
        	System.out.println("both m and n have equivalent values ");
        if (m != n)
        	System.out.println("m and n don't refer to same instance or memory location");

        Integer p = new Integer(10);
        Integer q = new Integer(10);
        q = p;
        if (p == q)
        	System.out.println("both p and q refer to same instance or memory location.");
        if (p.equals(q))
        	System.out.println("equivalent values");

The result is as expected.

both m and n have equivalent values 
m and n dont refer to same instance or memory location
both p and q refer to same instance or memory location.
equivalent values

But what about the following cases?

Case-2 :

Integer i2 = new Integer(1000);
Integer j2 =new Integer(1000);
if (i2 == j2) 
    System.out.println("== case2");
if (i2.equals(j2))
    System.out.println("equals case2");

Output:

equals case2

Case-3:

Integer i3 = 10;
Integer j3 = 10;
if (i3 == j3)
   System.out.println("== case3");
if (i3.equals(i3))
   System.out.println("equals case3");

Output:

== case3
equals case3

Case-4:

Integer i4 = 1000;
Integer j4 = 1000;
if (i4 == j4)
    System.out.println("== case4");
if (i4.equals(j4))
    System.out.println("equals case4");

Output:

equals case4

Now, You may be confused…you can notice that == and .equals behave differently when we call parametrized constructor and also when we assign values to the referrence variable.

I want to mention some concepts here, after understanding this, you can refer the cases again. Your doubts will be cleared.

Due to Auto-boxing, Integer values between -128 an 127 are cached. But why this range?
Well, the smallest range of values for smallest wrapper class is between –128 to 127 i.e. Byte.

For this range, compiler won’t create any new object if there is already one object present with that value(This concept works in all the cases of String. See case 5)

So for the case 1 & 3, compiler is creating objects having same memory allocation. Hence == is true for both the cases. (.equals() true for both the case as values are equivalent,right?)

Beyond the range of -128 to 127, compiler will create objects having different memory locations,

so == is false for case 2 & 4

Now what is the difference between two lines.
Line1:

Integer a = new Integer(10);

Line2:

Integer a = 10;

In Line1, 1 object of type Integer is created in the heap.
In Line2, it will become

Integer a = Integer.valueOf(10);

This instruction cause that the cache has to be initialized before you can used it.
The cache contains values from -128 to usually 127, this give 255 values that has to be initialized (new Integer(a)). And this cause such big memory usage.
Summerizing:

•a = new Interger(10); - Will create one Integer object,
•a = 10; - Will create at least 255 Integer objects and one array.

*FYI: The cache initialization does not depend of the boxed value. The cache is also initialized when you are boxing values lower then -128 and greater then usually 127.
*Edited: As Edwin told in the comments, we can customize the cache size also.

Case-5 (for String):

String a = "hello";
String b = "hello";
System.out.println(a == b); // true
System.out.println(a.equals(b)); // true

As I have said, compiler won’t create any new object if there is already one object present with that value. Hence is the output.
Case-6  (for user-defined class):

class MyClass 
{
  public static void main(String args[]) 
  {
    MyAnotherClass cs = new MyAnotherClass(2);
    MyAnotherClass c = new MyAnotherClass(2);
    if( cs.equals(c))
       System.out.println("Both objects are equal");
    else
       System.out.println("Unequal objects");
  }
}

class MyAnotherClass
{
   int i;
   MyAnotherClass() 
   {
      i=10;
   }
   MyAnotherClass(int a) 
   {
     this.i=a;
   }
}

Output:

Unequal objects

You may be expecting, the output should be the other one, but for user-defined class, the custom objects created have different instances, no matter what they contain. Hence is the output.

About these ads

4 thoughts on “[A Detailed Discussion] Difference between == and .equals() in Java

  1. You might want to consider altering the size of default cache. You can do that by setting the system property java.lang.Integer.IntegerCache.high= in whose case you can make you case #4 in your blog to use the cache. An alternative way to do this with Java HotSpot is to set -XX:AutoBoxCacheMax= in whose case you could make autoboxing cache to be used again, even for your case #4.

  2. Oh my good.. I stumbled upon this article and feel good after reading this. Thanks for such an informative article with full detailed explanation.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s