Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there any standard Java classes with inconsistent compareTo() and equals()?

Tags:

java

I'm looking for all standard Java classes for which compareTo() can return 0 while equals() returns false:

Comparable comparable1 = ???; Comparable comparable2 = ???;  assert comparable1.compareTo(comparable2) == 0; assert !comparable1.equals(comparable2); 

I know just one: new BigDecimal("1.0") is equal to new BigDecimal("1") using compareTo() but not equal using equals(). Are there any others?

I'm interested in all such classes, but only from public Java API. I need it to provide thorough documentation for AssertJ's UnevenComparableAssert interface.

EDIT:

Thanks to @ErikVesteraas, I've managed to reproduce additional example:

Calendar calendar1 = new GregorianCalendar(0, 0, 0); Calendar calendar2 = new GregorianCalendar(0, 0, 0); calendar2.setLenient(false);  Comparable comparable1 = calendar1; Comparable comparable2 = calendar2;  assert comparable1.compareTo(comparable2) == 0; // compareTo compares along the timeline assert !comparable1.equals(comparable2); // equals compares state, leniency is different 
like image 400
Michal Kordas Avatar asked May 10 '15 13:05

Michal Kordas


2 Answers

There actually seems to be a few examples, but some are not well documented in the code or JavaDoc. This blog post by Stephen Colebourne gives the details, but in summary the following classes are inconsistent with equals:

  • java.math.BigDecimal
  • java.io.ObjectStreamField
  • javax.management.ObjectName (have not been able to reproduce an example though)
  • java.util.Calendar
  • java.util.GregorianCalendar

For example:

ObjectStreamField a = new ObjectStreamField("foo", String.class); ObjectStreamField b = new ObjectStreamField("foo", String.class); a.equals(b); // false, checks object equality a.compareTo(b); // 0 

As noted by Olivier, Java 8 also adds java.time.zone.ZoneOffsetTransition

Notably java.time.OffsetTime has avoided inconsistency by adding extra methods isAfter, isBefore and isEqual for doing time-line comparison/equality-checking.

like image 189
Erik Vesteraas Avatar answered Sep 19 '22 12:09

Erik Vesteraas


Looking for "inconsistent with equals" in the JDK classes, I also found java.time.zone.ZoneOffsetTransition

like image 44
Olivier Croisier Avatar answered Sep 19 '22 12:09

Olivier Croisier