← Назад к вопросам

Какой тип данных возвращает hashCode?

1.0 Junior🔥 111 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Какой тип данных возвращает hashCode?

hashCode() возвращает тип **int** (32-битное целое число со знаком).

Сигнатура метода

public int hashCode() {
    // Возвращает int
    return hash;
}

Этот метод определен в классе Object, который является суперклассом для всех классов Java.

Почему именно int?

1. Размер в памяти

int занимает 32 бита, что обеспечивает хороший баланс:
  • Достаточно битов для представления большого диапазона значений (-2,147,483,648 до 2,147,483,647)
  • Не слишком много памяти в отличие от long (64 бита)

2. Совместимость с HashMap и HashSet

Внутренне HashMap использует hashCode для расчета индекса массива:

public class HashMap<K, V> {
    // Упрощено
    public V put(K key, V value) {
        int hash = key.hashCode();  // Получаем int
        int index = hash % table.length;  // Используем для индекса
        // ...
    }
}

3. Диапазон значений

Диапазон int (-2,147,483,648 до 2,147,483,647) достаточен для:

  • Распределения объектов по bucket'ам в HashMap
  • Минимизации коллизий
  • Работы с модульной арифметикой

Примеры

Default hashCode (из Object)

Object obj = new Object();
int hash = obj.hashCode();  // Возвращает int
System.out.println(hash);   // Что-то типа 705927765

Кастомная реализация hashCode

public class User {
    private String name;
    private int age;
    
    @Override
    public int hashCode() {
        // Возвращаем int
        return Objects.hash(name, age);
    }
}

User user = new User("John", 30);
int hash = user.hashCode();  // int
System.out.println(hash);    // Например: 1234567

Использование в HashMap

Map<User, String> map = new HashMap<>();
User key = new User("John", 30);

int hash = key.hashCode();   // Получаем int
int index = (hash & 0x7FFFFFFF) % map.size();  // Используем для индекса

map.put(key, "Developer");

Objects.hash() - удобный способ

public class Product {
    private String id;
    private String name;
    private BigDecimal price;
    
    @Override
    public int hashCode() {
        // Objects.hash() возвращает int
        return Objects.hash(id, name, price);
    }
}

Хеширование строк

Для строк Java использует специальный алгоритм, возвращающий int:

String str = "Hello";
int hash = str.hashCode();  // int

// Алгоритм для String:
// hash = 0;
// for (char c : str.toCharArray()) {
//     hash = 31 * hash + c;
// }

Примеры:

  • "Hello" → 69609650
  • "World" → 78454828

Коллизии (когда два объекта имеют одинаковый hashCode)

Object obj1 = new Object();
Object obj2 = new Object();

// Крайне редко (但возможно) имеют одинаковый hashCode
// но они не равны через equals()

int hash1 = obj1.hashCode();  // int
int hash2 = obj2.hashCode();  // int

// hash1 может == hash2, но obj1 != obj2
if (hash1 == hash2 && !obj1.equals(obj2)) {
    System.out.println("Коллизия!");
}

Договор hashCode() и equals()

public class Employee {
    private long id;
    private String name;
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Employee)) return false;
        Employee that = (Employee) o;
        return id == that.id;  // Сравниваем по id
    }
    
    @Override
    public int hashCode() {
        // Если два объекта равны по equals(), они ДОЛЖНЫ иметь одинаковый hashCode
        return Long.hashCode(id);
    }
}

Employee emp1 = new Employee(1, "John");
Employee emp2 = new Employee(1, "John");

// emp1.equals(emp2) == true
// emp1.hashCode() == emp2.hashCode()  // ОБЯЗАТЕЛЬНО!

Почему не long?

Если бы hashCode() возвращал long (64 бита) вместо int (32 бита):

public long hashCode() {  // НЕПРАВИЛЬНО
    return value;
}

Проблемы:

  • ❌ Больше памяти
  • ❌ Медленнее вычисления
  • ❌ HashMap рассчитан на int
  • ❌ Несовместимость с существующим кодом
  • ❌ Нет преимущества (32 бита достаточно)

Практический пример: HashSet

public class Demo {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        
        String str1 = "Hello";
        String str2 = "World";
        
        int hash1 = str1.hashCode();  // int: 69609650
        int hash2 = str2.hashCode();  // int: 78454828
        
        set.add(str1);  // Использует hash1 для индекса
        set.add(str2);  // Использует hash2 для индекса
        
        System.out.println(set.contains("Hello"));  // true
    }
}

Ключевые моменты

✓ hashCode() возвращает int ✓ int - это 32-битное целое число со знаком ✓ Диапазон: -2,147,483,648 до 2,147,483,647 ✓ Используется HashMap, HashSet и других hash-based коллекций ✓ Договор: если equals() возвращает true, hashCode() должен быть одинаков ✓ Используй Objects.hash() для реализации ✓ Коллизии возможны, но обрабатываются HashMap

int - это оптимальный размер для хеширования в Java: достаточно битов, но не слишком много.