Equivalence vs. Equality in Java String

Strings are one of the basic data types used in any programming language. Whether displaying text to a user or gathering input, strings will likely be part of that program. Strings are part of one of the first programs that everyone rights, "Hello World!"

From Hello World, new programmers quickly move on to other simple applications. These applications with include things like comparing and concatenating. This seems fairly straightforward, but can also be the cause of hard-to-trace bugs or bugs that can be easily missed. This is due to the difference between equivalence and equality.

In Java, when we have two string objects, and those same strings contain the same text they may, or may not be equal. Here is some code that shows this:

Running this code results in:

 cat is equal to cat: true
 cat1 is equal to cat1: false

The first two strings "testa" and "testb" are both "cat" and the second two strings "testa" and "tesb" are both "cat", but only the first is equal. Even though the variables are all the word "cat", they are not all equal. The fact that they are all the same means they are equivalent, but in Java, this does not mean they are equal.  

For a string to be equal in Java, it needs to be the exact string object. When two strings are created in the same way, Java to conserve resources will use a single object and memory location to hold the same string. We can see this in the debug log.

testa and testb both have an object id of 22. The string objects are the same object and are equal.

testc and testd though have different ids, even though they both contain the word "cat". This is because of the use of the + operand. Behind the scenes changing strings this way will result in a brand new string object being created. These two string objects, though they contain the same text, are equivalent but not equal.

Developers can run into issues when testing values if they are not aware of how string objects are stored. When testing a developer may input test strings and test a method that checks if they are equal (=) and the application will operate as expected. Then when the actual application is running, the real input could be concatenated values that will not equal because they are different objects.  

To avoid this issue, the string class contains a method called ".equals()". this method can be used to accurately compare strings even if they are different objects.

Running this code results in:

cat is equal to cat: true
cat is equal to cat: true

Knowing that equivalence and equality are different in java, it nearly always makes more sense to use the equals method rather than using a direct = comparison when comparing strings.