Skip to main content

What are the differences between the equality operator and the equals method?

The Java language offers the programmer more than one way to check for equality -- but all those ways are not created equal.
The equality operator == is a fundamental operator in the Java language. The result type of the expression is always boolean. According to 15.21 Equality Operators in Java Language Specification 3rd Edition:
  • For numeric types, the value produced by the == operator is true if the value of the left-hand operand is equal to the value of the right-hand operand; otherwise, the result is false.
  • For comparing boolean types, the result of == is true if the operands (after any required unboxing conversion) are both true or both false; otherwise, the result is false.
  • For comparing reference types, at run time, the result of == is true if the operand values are both null or both refer to the same object or array; otherwise, the result is false.
In contrast, the equals() is an instance method which is fundamentally defined by the java.lang.Object class. This method, by convention, indicates whether the receiver object is "equal to" the passed in object. According to java.lang.Object API document:
The equals method implements an equivalence relation on non-null object references:
  • It is reflexive: for any non-null reference value x, x.equals(x) should return true.
  • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
  • For any non-null reference value x, x.equals(null) should return false.
The equals() method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true). Other classes, including those you write, may override this method to perform more specialized equivalence testing.
Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.
The typical problem for most people is in using == to compare two strings (for example, strObj1 == strObj2) when they really should be using the String class's equals() method (for example, strObj1.equals(strObj2)). From above, you know that the operator will only return "true" when both of the references refer to the same actual object. But when comparing strings, in most cases, it's more common to determine whether or not the value of the two strings are the same -- since two different String objects may both have the same (or different) values.
For String Object:
  • The equals(Object anObject) method compares the characters that make up String objects. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object. Here is the equals code from String.java code:
    public boolean equals(Object anObject)
    {
      if (! (anObject instanceof String))
        return false;  //null or not String Object
      String str2 = (String) anObject;
      if (count != str2.count) 
        return false;  //The length of two String Object not the same
      if (value == str2.value && offset == str2.offset)
        return true;   //The argument String Object is the same this Object!!!
      int i = count;
      int x = offset;
      int y = str2.offset;
      while (--i >= 0)
        if (value[x++] != str2.value[y++])
          return false;
      return true;    //all the elements of the two char arrays are matched!!!
    }
  • The == operator determines if two operands refer to the same String object. The == actually tests to see if the references in the variables point to the same memory address.
For Example:
public class Program {
  public static void main(String[] args) {
    String str1 = new String("Hello");
    String str2 = new String("Hello");
    System.out.println("str1 == str2 is " + (str1 == str2));
    System.out.println("str1.equals(str2) is " + (str1.equals(str2)));
  }
}
The output is
str1 == str2 is false
str1.equals(str2) is true
Strings are immutable and their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared. The String manipulation methods take the source string as input and return an new string as output if there are any changes, otherwise the original string will be returned. Here is the substring code form String.java:
public String substring(int beginIndex, int endIndex)
{
  if (beginIndex < 0 || endIndex > count || beginIndex > endIndex)
    throw new StringIndexOutOfBoundsException();
  if (beginIndex == 0 && endIndex == count)
    return this;                              //No Changes
  int len = endIndex - beginIndex;
  // Package constructor avoids an array copy.
  return new String(value, beginIndex + offset, len,
        (len << 2) >= value.length);          //Generate a new String
}
Let's make an example for using substring function:
class Program {
  public static void main(String[] args) {
    String s = "ABCDEFG";
    String s1 = s.substring(0, 4);
    String s2 = s.substring(0, 4);
    String s3 = s.substring(0, s.length());
    System.out.println("s1 == s2 is " + (s1 == s2));
    System.out.println("s  == s3 is " + (s == s3));
  }
}
The output is
s1 == s2 is false  //Creates two new String objects
s  == s3 is true   //Returns the original String Object
To save space and reduce complexity, JVM uses a concept of string constant pool. For example:
public class Program {
  public static void main(String[] args) {
    String str1 = "Hello";
    String str2 = "Hello";
    System.out.println("str1 == str2 is " + (str1 == str2));
    System.out.println("str1.equals(str2) is " + (str1.equals(str2)));
  }
}
The output is
str1 == str2 is true
str1.equals(str2) is true
 

Comments

Popular posts from this blog

Asynchronous Vs. Synchronous Communications

Synchronous (One thread):   1 thread -> |<---A---->||<----B---------->||<------C----->| Synchronous (multi-threaded):   thread A -> |<---A---->| \ thread B ------------> ->|<----B---------->| \ thread C ----------------------------------> ->|<------C----->|

WebSphere MQ Interview Questions

What is MQ and what does it do? Ans. MQ stands for MESSAGE QUEUEING. WebSphere MQ allows application programs to use message queuing to participate in message-driven processing. Application programs can communicate across different platforms by using the appropriate message queuing software products. What is Message driven process? Ans . When messages arrive on a queue, they can automatically start an application using triggering. If necessary, the applications can be stopped when the message (or messages) have been processed. What are advantages of the MQ? Ans. 1. Integration. 2. Asynchrony 3. Assured Delivery 4. Scalability. How does it support the Integration? Ans. Because the MQ is independent of the Operating System you use i.e. it may be Windows, Solaris,AIX.It is independent of the protocol (i.e. TCP/IP, LU6.2, SNA, NetBIOS, UDP).It is not required that both the sender and receiver should be running on the same platform What is Asynchrony? Ans. With messag...

Advantages & Disadvantages of Synchronous / Asynchronous Communications?

  Asynchronous Communication Advantages: Requests need not be targeted to specific server. Service need not be available when request is made. No blocking, so resources could be freed.  Could use connectionless protocol Disadvantages: Response times are unpredictable. Error handling usually more complex.  Usually requires connection-oriented protocol.  Harder to design apps Synchronous Communication Advantages: Easy to program Outcome is known immediately  Error recovery easier (usually)  Better real-time response (usually) Disadvantages: Service must be up and ready. Requestor blocks, held resources are “tied up”.  Usually requires connection-oriented protocol