Анализатор обнаружил пользовательский тип, который переопределяет метод '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
Мы получили корректный результат: коллекция содержит только уникальные элементы.
Данная диагностика классифицируется как:
|