FAQ

Java

JSP

Servlet


Advertisement



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

Why? Please read What is String Literal Pool? in XyzWs Java FAQ.


Printer-friendly version Printer-friendly version | Send this 
article to a friend Mail this to a friend

Previous Next vertical dots separating previous/next from contents/index/pdf Contents

  |   |