Анализатор обнаружил пользовательский тип, который переопределяет метод 'equals', но не переопределяет метод 'hashCode', и наоборот. Это может привести к неправильному функционированию пользовательского типа в сочетании с такими коллекциями как HashMap, HashSet и Hashtable, так как они активно используют 'hashCode' и 'equals' в своей работе.
Рассмотрим пример с использованием HashSet:
public class Employee {
String name;
int age;
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String getFullInfo() {
return this.name + " - " + String.valueOf(age);
}
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof Employee))
return false;
Employee employee = (Employee) obj;
return employee.getAge() == this.getAge()
&& employee.getName() == this.getName();
}
}
public static void main(String[] args)
{
HashSet<Employee> employees = new HashSet<>();
employees.add(new Employee("OLIVER", 25));
employees.add(new Employee("MUHAMMAD", 54));
employees.add(new Employee("OLIVER", 25));
employees.forEach(arg -> System.out.println(arg.getFullInfo()));
}
В результате работы программы на консоль будет выведено:
OLIVER - 25
MUHAMMAD - 54
OLIVER - 25
Как видим, несмотря на то, что тип 'Employee' переопределяет метод 'equals', этого недостаточно. В ходе выполнения программы нам не удалось получить ожидаемого результата, и коллекция содержит повторяющиеся элементы. Для устранения этой проблемы в объявление типа 'Employee' необходимо добавить переопределение метода 'hashCode':
public class Employee {
...
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof Employee))
return false;
Employee employee = (Employee) obj;
return employee.getAge() == this.getAge()
&& employee.getName() == this.getName();
}
@Override
public int hashCode() {
int result=17;
result=31*result+age;
result=31*result+(name!=null ? name.hashCode():0);
return result;
}
}
public static void main(String[] args)
{
HashSet<Employee> employees = new HashSet<>();
employees.add(new Employee("OLIVER", 25));
employees.add(new Employee("MUHAMMAD", 54));
employees.add(new Employee("OLIVER", 25));
employees.forEach(arg -> System.out.println(arg.getFullInfo()));
}
Вновь выполним программу. В результате на консоль будет выведено:
MUHAMMAD - 54
OLIVER – 25
Мы получили корректный результат: коллекция содержит только уникальные элементы.
Данная диагностика классифицируется как:
|