У меня есть класс с полем float
. Например:
public class MultipleFields {
final int count;
final float floatValue;
public MultipleFields(int count, float floatValue) {
this.count = count;
this.floatValue = floatValue;
}
}
Мне нужно иметь возможность сравнивать экземпляры по значению. Теперь, как мне правильно реализовать равно
& hashCode
?
Обычный способ реализации equals
и hashCode
- это просто рассмотреть все поля. Например, Eclipse сгенерирует следующее равное
:
public boolean equals(Object obj) {
// irrelevant type checks removed
....
MultipleFields other = (MultipleFields) obj;
if (count != other.count)
return false;
if (Float.floatToIntBits(floatValue) != Float.floatToIntBits(other.floatValue))
return false;
return true;
}
(и аналогичный hashCode
, который по сути вычисляет count * 31 + Float.floatToIntBits (floatValue)
).
Проблема в том, что мои значения FP подвержены ошибкам округления (они могут поступать из-за ввода пользователем, из БД и т. Д.). Поэтому мне нужно «терпимое» сравнение.
Обычное решение - сравнивать с использованием значения epsilon (см., Например, Сравнение IEEE float и double на равенство ). Однако я не совсем уверен, как я могу реализовать равняется
с помощью этого метода и при этом иметь хэш-код
, который согласуется с равным
.
Моя идея состоит в том, чтобы определить количество значащих цифр для сравнения, а затем всегда округлять до этого количества цифр в обоих равных
и hashCode
:
long comparisonFloatValue = Math.round(floatValue* (Math.pow(10, RELEVANT_DIGITS)));
Затем, если я заменю все использование floatValue
с compareFloatValue
в равно
и hashCode
, я должен получить "терпимое" сравнение, которое согласуется с hashCode
.