Что означает возврат значения 0 из метода compare() в Java Comparator?

«Что означает возврат значения 0 из метода compare() в Java Comparator?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Возврат значения 0 из метода Comparator.compare(T o1, T o2) означает, что с точки зрения данного компаратора объекты o1 и o2 равны (эквивалентны) в контексте устанавливаемого порядка.

Последствия:

  • При сортировке (например, Collections.sort()) порядок двух объектов, для которых compare() вернул 0, относительно друг друга считается неопределённым (может сохраниться исходный).
  • В структурах данных, основанных на упорядочении (TreeSet, TreeMap), объекты с compare() == 0 рассматриваются как равные, даже если их метод equals() возвращает false. Это может привести к неожиданному "исчезновению" элементов.

Пример:

// Компаратор, сравнивающий строки только по их длине
Comparator<String> lengthComparator = (s1, s2) -> s1.length() - s2.length();

int result = lengthComparator.compare("cat", "dog"); // result = 0 (длины равны)
// Для этого компаратора строки "cat" и "dog" эквивалентны.

Важные правила и best practices:

  1. Согласованность с equals(): Желательно, чтобы выполнение условия compare(x, y) == 0 было эквивалентно x.equals(y). Если это не так, это должно быть явно задокументировано.
  2. Работа с null: Стандартные компараторы не принимают null. Для безопасного сравнения используйте Comparator.nullsFirst(comparator) или Comparator.nullsLast(comparator).
  3. Симметричность: Контракт требует, чтобы знак результата compare(x, y) был противоположен знаку compare(y, x).