Почему Equals и Hashcode одинаковы для списка объектов, хотя я не реализовал эти методы для этого объекта - PullRequest
2 голосов
/ 05 марта 2020

У меня есть 3 класса

Класс сотрудника похож на

  class Employee {
    int id;
    String name;
    long salary;
    List<Address> address;
    //getter setter, equals and hashcode and parameterized constructor}

И мой класс адресов равен

public class Address {
int housenum;
String streetname;
int pincode;
//getter setter and parameterized constructor
}

, а класс Мой тест похож на

 Address address1 = new Address(10, "str 1", 400043);
            Address address2 = new Address(10, "str 1", 400043);

            List<Address> addressLst1= new ArrayList<>();
            List<Address> addressLst2= new ArrayList<>();
            addressLst1.add(address1);
            addressLst1.add(address2);
            addressLst2.add(address1);
            addressLst2.add(address2);
            Employee employee1 = new Employee(1, "EMP1", 1000, addressLst1);
            Employee employee2 = new Employee(1, "EMP1", 1000, addressLst2);

            Set<Employee> set = new HashSet<>();
            set.add(employee1);
            set.add(employee2);

            System.out.println(":::::::::::::::addressLst1:::::::::" + addressLst1.hashCode());
            System.out.println(":::::::::::::::addressLst2:::::::::" + addressLst2.hashCode());

            System.out.println(":::::::::::::::address1:::::::::" + address1.hashCode());
            System.out.println(":::::::::::::::address2:::::::::" + address2.hashCode());

            System.out.println(":::::::::::::::employee1:::::::::" + employee1.hashCode());
            System.out.println(":::::::::::::::employee2:::::::::" + employee2.hashCode());

            set.forEach(System.out::println);

            System.out.println(":::::::::::::::size:::::::::" + set.size());

Я получаю другой хеш-код для объектов адреса, поскольку я не переопределил equals и hashcode. Но почему я получаю один и тот же хэш-код для двух разных списков адресов, т.е. addressLst1 и addressLst2 И почему я получаю размер, равный 1, почему хеш-код объекта-сотрудника одинаков? И как правильно переопределить equals и hashcode для пользовательского объекта, состоящего из списка другого пользовательского объекта?

1 Ответ

2 голосов
/ 05 марта 2020

Два List s addressLst1 и addressLst2 содержат одинаковые элементы в точно том же порядке, поэтому контракт List equals требует, чтобы эти два List были равны друг другу:

логическое java .util.List.equals (объект o)

Сравнивает указанный объект с этим списком на равенство. Возвращает true тогда и только тогда, когда указанный объект также является списком, оба списка имеют одинаковый размер, и все соответствующие пары элементов в двух списках равны. (Два элемента e1 и e2 равны, если (e1 == null? E2 == null: e1.equals (e2)).) Другими словами, два списка определяются как равные, если они содержат одинаковые элементы в одинаковом порядке. , Это определение гарантирует, что метод equals работает правильно в разных реализациях интерфейса List.

Не имеет значения, что Address не переопределяет equals и hashCode, поскольку List s содержат ссылки на одни и те же объекты. Хотя address1 не равно address2, оба List s содержат ссылки на address1 и address2 в одном и том же порядке, поэтому List s равны.

Для Employee class, вы писали, что переопределяете equals и hashCode, поэтому я предполагаю, что два Employees равны, если все их свойства равны. Поэтому два Employee экземпляра, которые вы пытаетесь добавить к Set, равны.

...