Переопределите equals и hashCode по a и b. Для float используйте Float.compare и согласованное хеширование, чтобы корректно обработать NaN и знаковый ноль.
Гарантирование уникальности объектов в HashSet
Переопределите equals и hashCode по a и b. Для float используйте Float.compare и согласованное хеширование, чтобы корректно обработать NaN и знаковый ноль.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
В коллекцию HashSet<Value> помещаются два экземпляра класса Value с одинаковыми полями (a = 1, b = 1f). Необходимо реализовать корректные методы сравнения и хеширования в классе Value, чтобы HashSet воспринимал такие объекты как один и обеспечивал уникальность элементов.
import java.util.HashSet;
import java.util.Set;
public class JetbulbInterview {
public static void main(String[] args) {
Set<Value> values = new HashSet<>();
Value v1 = new Value(1, 1f);
Value v2 = new Value(1, 1f);
values.add(v1);
values.add(v2);
System.out.println(values);
}
}
class Value {
int a;
float b;
public Value(int a, float b) {
this.a = a;
this.b = b;
}
@Override
public String toString() {
return "Value{" +
"a=" + a +
", b=" + b +
'}';
}
}
Ответ
Переопределите equals и hashCode по a и b. Для float используйте Float.compare и согласованное хеширование, чтобы корректно обработать NaN и знаковый ноль.
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (other == null || getClass() != other.getClass()) return false;
Value value = (Value) other;
return a == value.a && Float.compare(b, value.b) == 0;
}
@Override
public int hashCode() {
return 31 * Integer.hashCode(a) + Float.hashCode(b);
}
Добавьте методы в Value; поля лучше сделать final. Тогда два объекта из примера дадут один элемент HashSet. Эта семантика считает NaN равным NaN и различает +0.0f и -0.0f. При другом бизнес-правиле нужно одновременно согласовать и equals, и hashCode.