I have an object, Foo
which inherits the default equals
method from Object
, and I don't want to override this because reference equality is the identity relation that I would like to use.
I now have a specific situation in which I would now like to compare these objects according to a specific field. I'd like to write a comparator, FooValueComparator
, to perform this comparison. However, if my FooValueComparator
returns 0 whenever two objects have the same value for this particular field, then it is incompatible with the equals method inherited from Object, along with all the problems that entails.
What I would like to do would be to have FooValueComparator
compare the two objects first on their field value, and then on their references. Is this possible? What pitfalls might that entail (eg. memory locations being changed causing the relative order of Foo
objects to change)?
The reason I would like my comparator to be compatible with equals is because I would like to have the option of applying it to SortedSet
collections of Foo
objects. I don't want a SortedSet
to reject a Foo
that I try to add just because it already contains a different object having the same value.
This is described in the documentation of
Comparator
:It short, if the implementation of
Comparator
is not consistent withequals
method, then you should know what you're doing and you're responsible of the side effects of this design, but it's not an imposition to make the implementation consistent toObject#equals
. Still, take into account that it is preferable to do it in order to not cause confusion for future coders that will maintain the system. Similar concept applies when implementingComparable
.An example of this in the JDK may be found in
BigDecimal#compareTo
, which explicitly states in javadoc that this method is not consistent withBigDecimal#equals
.If your intention is to use a
SortedSet<YourClass>
then probably you're using the wrong approach. I would recommend using aSortedMap<TypeOfYourField, Collection<YourClass>>
(orSortedMap<TypeOfYourField, YourClass>
, in case there are no equals elements for the same key) instead. It may be more work to do, but it provides you more control of the data stored/retrieved in/from the structure.