Difference between String#equals and String#contentEquals methods
The String#equals()
not only compares the String's contents, but also checks if the other object is also an instance of a String
. The String#contentEquals()
only compares the contents (the character sequence) and does not check if the other object is also an instance of String
. It can be anything as long as it is an implementation of CharSequence
which covers a.o. String
, StringBuilder
, StringBuffer
, CharBuffer
, etc.
To put it easily: String.contentEquals()
is the smarter brother of String.equals()
, because it can be more free in the implementation than String.equals()
.
There are some reasons why there is a separate String.contentEquals()
method. The most important reason I think is:
- The
equals
method has to be reflexive. That means that:x.equals(y) == y.equals(x)
. This implies thataString.equals(aStringBuffer)
would have to be the same asaStringBuffer.equals(aString)
. This would require the Java API developers to make some special implementation for Strings in theequals()
method of StringBuffer, StringBuilder and CharSequence as well. This would be a mess.
This is where String.contentEquals
comes in. This is a standalone method that does not have to follow the strict requirements and rules for Object.equals
. This way, you can implement the sense of "equal content" more freely. This allows you to make intelligent comparisons between a StringBuffer and a String, for example.
And to say what exactly the difference is:
String.contentEquals()
can compare the contents of aString
, aStringBuilder
, aStringBuffer
, aCharSequence
and all derived classes of these. If the parameter is of type String, thenString.equals()
get executed.String.equals()
only compares String objects. All other object types are considered as not equal.String.contentEquals()
can compareStringBuffer
andStringBuilder
in an intelligent way. It does not call the heavytoString()
method, which copies the whole content to a new String object. Instead, it compares with the underlyingchar[]
array, which is great.
This answer was already posted by dbw but he deleted it but he had some very valid points for the difference while comparing execution time, what exceptions are thrown,
If you look at the source code String#equals and String#contentEquals it is clear that there are two overridden methods for String#contentEquals
one which take StringBuilder
and other CharSequence
.
The difference between them,
-
String#contentEquals
will throw NPE if the argument supplied isnull
butString#equals
will returnfalse
-
String#equals
compares the content only when the argument supplied isinstance of String
otherwise it will returnfalse
in all other cases but on the other handString#contentEquals
checks the content of all the objects which implement interfaceCharSequence
. -
You can also tweak the code so that
String#contentEquals
return the wrong result or result you want by overridingequals
method of the argument passed as shown below but you can not do those tweaks withString#equals
.
Below code will always producetrue
as long ass
contains anystring
which is 3 character longString s= new String("abc");// "abc"; System.out.println(s.contentEquals(new CharSequence() { @Override public CharSequence subSequence(int arg0, int arg1) { // TODO Auto-generated method stub return null; } @Override public int length() { // TODO Auto-generated method stub return 0; } @Override public char charAt(int arg0) { // TODO Auto-generated method stub return 0; } @Override public boolean equals(Object obj) { return true; } }));
String#contentEquals
will be slower thenString#Equals
in the case when argument supplied isinstance of String
and the length of bothString
is same but contents are not equal.
Example if the string areString s = "madam"
andString argPassed = "madan"
thens.contentEquals(argPassed)
will take almost double execution time in this case as compared tos.equals(argPassed)
If the content length are not same for both the strings then function
String#contentEquals
will have better performance thenString#Equals
in almost all possible cases.
One more point to add to his answer
-
String#contentEquals
of aString
object will also compare to theStringBuilder
contents and provide the appropriate result whileString#Equals
will returnfalse