Может ли метод hashCode() в Java возвращать отрицательное число?

«Может ли метод hashCode() в Java возвращать отрицательное число?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, метод hashCode() может и часто возвращает отрицательные числа. Возвращаемый тип int имеет диапазон от -2^31 до 2^31-1. Отрицательный хэш-код является абсолютно валидным.

Примеры:

System.out.println("hello".hashCode()); // 99162322 (положительный)
System.out.println("Hello".hashCode()); // 69609650 (положительный)
System.out.println("password".hashCode()); // 488896668 (положительный)
System.out.println("z".hashCode()); // 122 (положительный)
// Многие переопределённые hashCode() могут давать отрицательные значения
System.out.println(new Object().hashCode()); // Может быть любым int

Как коллекции работают с отрицательными хэшами? Классы вроде HashMap внутренне преобразуют хэш-код для вычисления индекса корзины (bucket). Они используют побитовые операции, которые корректно работают с отрицательными числами.

Важное предупреждение:

// НЕДОПУСТИМЫЙ подход для приведения к неотрицательному индексу
int index = Math.abs(obj.hashCode()) % tableSize;
// Проблема: Math.abs(Integer.MIN_VALUE) возвращает ОТРИЦАТЕЛЬНОЕ значение (переполнение).

// КОРРЕКТНЫЙ подход (аналогичный HashMap):
int hash = obj.hashCode();
int index = (hash & 0x7fffffff) % tableSize; // Обнуляем знаковый бит
// Или, что чаще:
int index = (table.length - 1) & hash; // Побитовое И с маской

Главное правило: Контракт hashCode() требует только консистентности в рамках одного выполнения приложения и согласованности с equals(). Знак значения не имеет значения.