Best implementation for hashCode method for a collection
Лучшая реализация метода hashCode для коллекции
Как нам выбрать наилучшую реализацию hashCode() метода для коллекции (при условии, что метод equals был переопределен правильно)?
Переведено автоматически
Ответ 1
Лучшая реализация? Это сложный вопрос, потому что это зависит от шаблона использования.
Почти для всех случаев разумно хорошая реализация была предложена в "Эффективной Java" Джоша Блоха в пункте 8 (второе издание). Лучше всего посмотреть его там, потому что автор объясняет, почему этот подход хорош.
Краткая версия
Создайте int result и присвоите ненулевое значение.
Для каждого поля,f протестированного в equals() методе, вычислите хэш-код c с помощью:
Если поле f равно a boolean: вычислить(f ? 0 : 1);
Если поле f равно byte, char, short или int: вычислить (int)f;
Если поле f равно a long: вычислить(int)(f ^ (f >>> 32));
Если поле f равно a float: вычислитьFloat.floatToIntBits(f);
Если поле f является a double: вычислите Double.doubleToLongBits(f) и обработайте возвращаемое значение, как любое длинное значение;
Если поле f является объектом: используйте результат hashCode() метода или 0, если f == null;
Если поле f является массивом: рассматривайте каждое поле как отдельный элемент и вычисляйте значение хэша рекурсивным способом и объединяйте значения, как описано далее.
Объедините хэш-значение c с result:
result = 37 * result + c
Возврат result
Это должно привести к правильному распределению значений hash для большинства ситуаций использования.
Ответ 2
Если вас устраивает эффективная реализация Java, рекомендованная dmeister, вы можете использовать вызов библиотеки вместо того, чтобы создавать свою собственную:
Для этого требуется либо Guava (com.google.common.base.Objects.hashCode), либо стандартная библиотека Java 7 (java.util.Objects.hash), но работает так же.
result = 31 * result + Arrays.hashCode(arrayField); // var bits » 32-bit
result = 31 * result + referenceField.hashCode(); // var bits » 32-bit (non-nullable) result = 31 * result + // var bits » 32-bit (nullable) (nullableReferenceField == null ? 0 : nullableReferenceField.hashCode());
return result;
}
Редактировать
Обычно, когда вы переопределяете hashcode(...), вы также хотите переопределить equals(...). Итак, для тех, кто будет или уже реализован equals, вот хорошая ссылка с моего Github...
Лучше использовать функциональность, предоставляемую Eclipse, которая выполняет довольно хорошую работу, и вы можете приложить свои усилия и энергию к разработке бизнес-логики.