Java string equals()

In this article, we will take a deep dive into equals() method of java string with examples.
This article will cover below topics in detail

Overview
Java string equals() method is used to check if one string is equal to another string or not. Thus, it is one of the ways of string comparison in java.

Java documentation for equals() method states,

Compares this string to the specified object. 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, this object means the string which invokes equals().
Syntax
equals() method accepts a single argument, which is of the type java.lang.Object. Typically, we pass a string as argument.
It compares the argument value with the value of string on which it is invoked.
Return value
equals() method returns true or false. It will return true, if the argument is a string and its value is the same as the value of string on which it is called.
How string equals() works
You can create a string in 2 ways in java.

First is directly defining a string and assigning it a value as String s = "abc";
Second is, creating an object as String s = new String("abc");

If two strings with same value are created using first syntax, their references will be same since they will be pointing to a same string in String constant pool as shown below.
JVM string pool

If both or any one of the string is created using the object syntax, then their references will be different even if their values are same.

Java string equals() makes use of this concept and it first checks the reference of both the strings before comparing their values.

If the references are same, then obviously both the strings represent the same value and hence, they are equal.

If the references are different, then it compares the value of both strings on a character by character basis.
As soon as it finds the first mismatch, it returns false. If all the characters match, it returns true.

Before checking for the values of objects, it also confirms that the argument string is in fact, a string.
If it is some other object, then it will straightaway return false, since equals() method is for testing equality of strings only.

Take a look at below source code of equals() method to further grasp the internal working.

public boolean equals(Object anObject) {
  if (this == anObject) {
    return true;
  }
  if (anObject instanceof String) {
    String aString = (String)anObject;
    if (!COMPACT_STRINGS || this.coder == aString.coder) {
      return StringLatin1.equals(value, aString.value);
    }
  }
  return false;
}

Java string equals() example
Below is an example program to show the usage of equals() method for testing string equality.

String s = "codippa";
String s1 = ".com";
String s2 = new String("codippa");
String s4 = new String("codippa");
    
System.out.println(s.equals(s1)); // false
System.out.println(s.equals(s2)); // true
System.out.println(s1.equals(s4)); // true
System.out.println(s2.equals(s4)); // true

Output is

false
true
true
true

A. In the first comparison, “codippa” is compared with “.com” and both are string references.
This will be definitely false.
B. In the second comparison, “codippa” is compared with a string object having value “codippa”.
Since, both have same values, it will be true.
C. In the third comparison, “.com” is compared with a string object having value “codippa”.
Since, both have different values, it will be false.
D. Finally, in the last comparison,  two string objects having same values “codippa” are compared.
Since, the values are same, the result will be true.
String equals() with case
equals() performs case sensitive comparison of strings.
This means that even if the string values are same but their case is different, the result will be false. Example,

String s = "codippa";
String s1 = "Codippa";
boolean r = s.equals(s1); // false

String equals() with null
You can supply a null value as argument to equals() method. But, the result of comparison will always be false. Example,

String s = "codippa";
System.out.println(s.equals(null)); // false

The reason is that equals() internally checks if the argument object is of String type using instanceof operator.
And, null instanceof String will always be false. So, the end result is also false.

Secondly, you cannot call equals() on a null reference as this will raise NullPointerException before even calling equals().

String equals() with objects
equals() method accepts an Object argument. This means that you can pass any object to it.

As stated before, equals() method checks if the argument object is a string using instanceof operator.
Thus, if you supply any other object as argument, the result will be false.

This can be verified with below example.

String s = "codippa";
Integer i = new Integer(10);
Boolean b = new Boolean(false);
System.out.println("String with Integer: " + s.equals(i));
System.out.println("String with Boolean: " +s.equals(b));

Output will be

String with Integer: false
String with Boolean: false

String equals() vs ==
== compares String object references and their value.

If both the strings are created using direct assignment, == will return
true, if their values are same.
false, if their values are different.

However, == will return false if one string is created using direct assignment and another string using new operator even if their values are same.
This is because their references will be different.

equals() tests for reference first and then the values. If references are different, then it checks the values.
Thus, equals() will return true, if and only if the strings have same value irrespective of one created as an object and other created as a direct assignment. Example,

String s = "codippa";
String s1 = "codippa";
String s2 = ".com";
String s3 = new String("codippa");
String s4 = new String(".com");
System.out.println("== with same values: " + 
    (s == s1)); // true
System.out.println("== with different values: " + 
    (s == s2)); // false
System.out.println("== with reference & object having same value: "
     + (s1 == s3)); // false
System.out.println("equals() with objects having same values: " + 
     s.equals(s3)); // true
System.out.println("equals() with objects having different values: "
     + s.equals(s4)); // false

Output will be

== with same values: true
== with different values: false
== with reference & object having same value: false
equals() with objects having same values: true
equals() with objects having different values: false

Above examples shows that == will result in false for a direct assignment string and a string created with new, even if they have same values.
String equals() best practice
Though equals() will always return true or false values but its invocation may also result in raising NullPointerException as shown in the example below.

String s = null;
boolean r = s.equals("someother");

You can be vigilant about not calling equals() on a null string.
But, it might happen that the string is generated at run time from a REST Api call, a database or as a return value from another method, as below

// get from a method
String s = generateToken();
boolean r = s.equals("someother");

In such case, if the returned value is null, you will get an exception.

It is not a best practice to surround each equals() call inside a try-catch block for handling NullPointerException.

So, the possible solutions are

1. If any one of the string is a constant or a pre-defined string that you are sure that will never be null, always invoke equals() on that, such as "someother".equals(s).

2. If both the strings are dynamic and can be null, then perform a null check on the string on which equals() will be invoked as below.

String s = getToken();
if(s != null) {
  s.equals("abc");
}

3. Create a static utility method passing it the strings to be compared as arguments. Example,

public static equals(String s1, String s2) {
  if(s1 == null) {
    return false;
  }
  return s1.equals(s2);
}

4. Use Java 8 Optional as below

String s = getToken();
Optional<String>sOp = Optional.ofNullable(s);
if(sOp.isPresent()) {
  s = sOp.get();
  boolean r = s.equals(s1);
}

Java 8 Optional was designed to avoid NullPointerException only. Its ofNullable() method creates an empty Optional, if the supplied value is null.
In that case, its isPresent() method will return false.
String equals() vs compareTo()
Both equals() and compareTo() method are used for string comparison. But, there are following differences between the two.
1. equals() can be used to test if two strings are same or equal. compareTo() can be used to check if two strings are equal and if one string is lesser or  greater than other.
Lesser and greater means that it alphabetically before or after another string.
2. equals() return true and false values only while compareTo() returns an integer value among -1, 0 and 1 depending on the values of strings.

Hope the article on String equals() method was informative.