Существуют ли стандартные классы Java с несогласованными compareTo() и equals()?
Я ищу все стандартные классы Java, для которых compareTo()
может возвращать 0
, а equals()
возвращает false
:
Comparable comparable1 = ???;
Comparable comparable2 = ???;
assert comparable1.compareTo(comparable2) == 0;
assert !comparable1.equals(comparable2);
Я знаю только один: new BigDecimal("1.0")
равен new BigDecimal("1")
, используя compareTo()
, но не равный с помощью equals()
. Есть ли другие?
Меня интересуют все такие классы, но только из открытого Java API. Мне нужно, чтобы предоставить подробную документацию для AssertJ UnevenComparableAssert
.
EDIT:
Благодаря @ErikVesteraas мне удалось воспроизвести дополнительный пример:
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
Ответы
Ответ 1
На самом деле, похоже, несколько примеров, но некоторые из них плохо документированы в коде или JavaDoc. Это сообщение в блоге от Stephen Colebourne дает подробности, но в целом следующие классы несовместимы с равными:
Например:
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
Как отметил Оливье, Java 8 также добавляет java.time.zone.ZoneOffsetTransition
В частности java.time.OffsetTime избегает несогласованности, добавляя дополнительные методы isAfter
, isBefore
и isEqual
сравнение строк/проверка равенства.
Ответ 2
Ищем "несовместимые с равными" в классах JDK, я также нашел java.time.zone.ZoneOffsetTransition