Доброго времени суток.
Задача: имеется следующий класс
public class Products {
public final Product PRODUCT;
public final double AMOUNT;
public final BigDecimal PRICE;
public final BigDecimal CALORIES;
public Products(Product product,
double amount,
BigDecimal price,
BigDecimal calories) {
PRODUCT = product;
AMOUNT = amount;
PRICE = price;
CALORIES = calories;
}
}
Необходимо переопределить для данного класса метод equals() и hashCode(). Все поля должны участвовать в переопределяемых методах. И самое главное - при сравнении полей PRICE и CALORIES необходимо сравнивать только значения без учета масштаба, т.е. при сравнении двух BigDecimal со значениями 12 и 12.000000 должно возвращаться true. Как я пытался решить задачу:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Products that = (Products) o;
return Double.compare(that.AMOUNT, AMOUNT) == 0 &&
Objects.equals(PRODUCT, that.PRODUCT) &&
PRICE.compareTo(that.PRICE) == 0 &&
CALORIES.compareTo(that.CALORIES) == 0;
}
@Override
public int hashCode() {
int result = 17;
result = result * 31 + PRODUCT.hashCode();
result = result * 31 + Double.hashCode(AMOUNT);
result = result * 31 + PRICE.hashCode();
result = result * 31 + CALORIES.hashCode();
return result;
}
В чем проблема: Метод equals() сравнивает BigDecimal без учета масштаба, а hashCode() использует BigDecimal::hashCode(), который вычисляет значения с учетом масштаба. Вопрос: как рассчитать hashCode для BigDecimal без учета масштаба?
Я бы пошел от обратного. В реальной жизни цена у вас не может быть с произвольным количеством знаков после запятой. То же самое с калорийностью и количеством (количество я бы тоже хранил в BigDecimal
).
Можно в конструкторе принудительно устанавливать требуемый масштаб, после этого hashCode()
у вас будет считаться одинаково для одинаково для одинаковой цены, калорийности, количества.
public class Products {
public final Product PRODUCT;
public final BigDecimal AMOUNT;
public final BigDecimal PRICE;
public final BigDecimal CALORIES;
public Products(Product product,
BigDecimal amount,
BigDecimal price,
BigDecimal calories) {
PRODUCT = product;
AMOUNT = amount.setScale(3, BigDecimal.ROUND_HALF_UP); // до грамм
PRICE = price.setScale(2, BigDecimal.ROUND_HALF_UP); // до копеек
CALORIES = calories.setScale(4, BigDecimal.ROUND_HALF_UP); // до 1/10000
}
}
Методы equals
и hashCode
не меняются.
можно взять doubleValue
у BigDecimal
и затем уже брать hash
@Override
public int hashCode() {
int result = 17;
result = result * 31 + PRODUCT.hashCode();
result = result * 31 + Double.hashCode(AMOUNT);
result = result * 31 + PRICE.hashCode();
result = result * 31 + Double.hashCode(CALORIES.doubleValue())
return result;
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Всем привет! Я только новичок и пытаюсь разобраться с циклом for в Java
Есть метод в кодеОн подключается к базе и заносит туда значения
Есть класс, в котором есть 3 функцииДве из них должны возвратить значение