Java: use toString (). Equals () vs. equals ()
This is a matter of theory. I have an object of my own design with a bunch of variables, methods, etc. I tried the toString method, mainly for logging, to return the value of the variables. It seems to me that the simplest and easiest way to compare instances of this object is to compare what is returned from the toString method. For example, the equals method might look like
public boolean equals(MyObject instance)
{
return toString().equals(instance.toString());
}
Is there a reason not to do this?
source to share
One reason to avoid this pattern would be speed: to compare for equality with using, toString()
you must do this:
- Create a temporary object
String
for the objectthis
- Create a temporary object
String
for the objectinstance
- Compare the first
String
character with the secondString
character - Make temporary strings available for garbage detection
You can skip most of this if you do the comparison directly. For example, comparing int
directly requires comparing 4 bytes, whereas comparing their string representation takes up to nine byte comparisons. Similar situations happen with other data types.
source to share
There are performance considerations for not doing what you ask, which dasblinkenlight summarized briefly.
Another important reason to avoid this pattern relates to the general contract for a method toString()
. All overridden methods of the Object class have a common contract. Because these methods are inherited by every class that you define in Java, and because they are overridden so often in many custom classes, it is very important to know and stick to your general contracts.
The general contract for toString()
is the simplest of the Object methods:
Returns the string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be concise, but informative and easy for a human to read. It is recommended that all subclasses override this method.
There is no requirement for the string returned by toString () to conform to a specific format, and there is no requirement to specify the format of the string returned as part of your API.
Since this is the case, the string representation of an object that is returned by toString () is most often an implementation detail that can change freely from one version of your class to the next. Changing the string representation returned toString()
can lead to program crashes if you base equal comparisons on them.
Another reason not to rely on method comparisons toString()
is that it doesn't provide your class with the necessary infrastructure to be used with the Java Collections Framework. Java class classes require well-formed methods equals()
and hashCode()
for the objects stored in them to work properly:
-
If there is a chance that the class you are writing will be used in any of the Java Collections Framework classes and / or that it may be used by another programmer, it is worth paying well-formed
equals()
andhashCode()
. -
Since the performance of any reasonably well-formed method
equals()
will outperform the performance of string-based matchingtoString()
... and since many classes must have a well-formed equals () method anyway ... you can just go ahead and use a custom methodequals()
.
source to share