Могу ли я использовать хеш-код члена класса для класса?

У меня есть класс с финальной строкой в ​​качестве уникального идентификатора. Конечно, я хочу переопределить equals, поэтому сравнение основано только на ID. Правильно ли тогда просто возвращать хэш-код идентификатора, как показано ниже?

class ItemSpec{
    final String name;

    ...

    @Override
    public boolean equals(Object o){
        if(o != null && o instanceof ItemSpec){
            return name.equalsIgnoreCase(((ItemSpec)o).name);
        } else{
            return false;
        }
    }

    @Override
    public int hashCode(){
         if(name == null){
             return 0;
         } else{
             return name.hashCode();
         }
    }
}

2 ответа

Решение

Нет, если ваши равные не чувствительны к регистру. Вы могли бы иметь два ItemSpec получается равным, но с разными хэш-кодами. Это нарушает самое важное требование хеш-кода.

Ваш equals должен согласиться с вашим hashCode, Поэтому, если вы собираетесь сравнивать их без учета регистра, вы должны написать свой hashCode без учета регистра.

@Override
public int hashCode(){
     if (name == null){
         return 0;
     } else{
         return name.toLowerCase().hashCode();
     }
}

Также ваш hashCode метод подразумевает, что name может быть нулевым. Если это так, вы должны проверить это в своем equals метод также.

Я не вижу никаких проблем с вашим подходом.

Но я часто видел следующую реализацию:

public int hashCode() {
    final int prime = 31;
    int result = super.hashCode();
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    return result;
}

Обновление: вот ссылка с лучшим объяснением: Лучшая реализация метода hashCode

Другие вопросы по тегам