Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't Java's `equals()` do deep comparison by default

Tags:

java

equals

It is well-known that the equals() method of an object, if not overridden, is a "shallow comparison" that is equivalent to using the "==" operator. (See, for example, https://docs.oracle.com/javase/tutorial/java/IandI/objectclass.html.)

Question: why doesn't Java provide a "deep-comparison" equals() method by default? That is, one that will invoke equals() on each of its instance variables recursively. Eventually, the recursion will reach primitive types and stop. Are there any downsides if this deep-comparison equals was the default?

like image 681
flow2k Avatar asked Jun 26 '17 21:06

flow2k


2 Answers

Are there any downsides if this deep-comparison equals was the default?

Yes. These include:

  • The default implementation cannot distinguish between references that are part of the logical value of the object, and references that are just associations with other objects. For example, say you have a Person class that references a company. You have two Person instances with the same name, SSN, DOB, etc. One references an old company. You may want the two Person instances, that reference the same actual person, to be equal, even though one has an outdated association.
  • A deep equality test would frequently be slower than the current default, possibly significantly slower. Frequently this would be unnecessary. The current default insures that the equality test is always fast unless someone specifies otherwise explicitly.
  • A deep comparison would need to handle cycles in the references. This would require some way to remember what objects had already been traversed. This would require memory to track those objects, potentially a significant amount of memory. An equality test could lead to an OutOfMemoryError.

The current default implementation is fast and makes no assumptions. It's a good default. Sometimes you will need to override the default, using your knowledge about what the logical value of the object contains, regardless of its root physical representation.

like image 131
Andy Thomas Avatar answered Sep 16 '22 22:09

Andy Thomas


A deep compare is much more complex and time consuming than a comparison of two references. This might be ok for simple objects, but when you have really complex data structures (e.g. a tree with ten thousand elements) how should the system know how "deep" the compare should be?

like image 24
Florian S. Avatar answered Sep 19 '22 22:09

Florian S.