JavaRush /Java блогы /Random-KK /Java тіліндегі equals() және hashCode() әдістерін шамадан...
Coder
Деңгей

Java тіліндегі equals() және hashCode() әдістерін шамадан тыс жүктеу

Топта жарияланған

Java тіліндегі equals() және hashCode() әдістерін қайта анықтау

Equalsжәне hashCodeолар сыныпта жарияланған Objectжәне стандартты Java кітапханаларында қамтылған іргелі әдістер болып табылады. Java тіліндегі equals() және hashCode() әдістерін шамадан тыс жүктеу - 1Әдіс нысандарды салыстыру және an object үшін бүтін codeты жасау үшін еquals()қолданылады . hashCodeБұл әдістер Java стандартты кітапханаларында an objectілерді кірістіру және алу кезінде кеңінен қолданылады HashMap. Әдіс басқа іске асыруларда, сондай-ақ an objectілерді салыстыруды қажет ететін кез келген басқа жағдайларда equalғана бірегей нысандардың сақталуын қамтамасыз ету үшін қолданылады . Сыныптағы әдістің әдепкі орындалуы айнымалылар сақтайтын жад мекенжайларына сілтемелерді салыстырады және мекенжайлар сәйкес келсе ғана қайтарады, басқаша айтқанда, айнымалылар бір нысанға сілтеме жасайды. Салыстыру табиғи логикаға немесе іскерлік логикаға сәйкес орындалады деп күтсеңіз, Java және әдістерді қайта анықтауды ұсынады. Стандартты Java кітапханаларындағы көптеген сыныптар оларды қайта анықтайды, мысалы, салыстырылатын екі нысанның мазмұны бірдей болса, оны қайтаратындай класс қайта анықтайды . Қаптама класы сандық салыстыруды орындау әдісін қайта анықтайды және т.б. Java сондай -ақ оларды және салыстыру әдістеріне сүйенетіндіктен , Java осы әдістерді қайта анықтау үшін келесі ережелерді ұсынады: HashSetSetequals()java.lang.Objecttrueequals()hashCode()StringequalstrueIntegerequalHashMapHashTableequals()hashCode()keyvalues
  1. Рефлексивтілік: an object өзіне тең болуы керек.
  2. Симметриялық: егер a.equals(b)ол қайтарса true, онда b.equals(a)ол да қайтарылуы керек true.
  3. Транзитивтілік: егер a.equals(b)ол қайтарса trueжәне b.equals(c)де қайтарса true, онда c.equals(a)ол да қайтарылуы керек true.
  4. Жүйелілік: әдіске қайталанатын қоңыраулар equals()нысанның кейбір сипат мәндері өзгертілмесе, бірдей мәнді қайтаруы керек. Яғни, Java тілінде екі нысан тең болса, олардың қасиеттері өзгеріссіз қалғанша олар тең болады.
  5. Салыстыру null: an objectіні тексеру керек null. Егер нысан тең болса null, онда әдіс falseемес қайтару керек NullPointerException. Мысалы, a.equals(null)ол қайтарылуы керек false.

Java тіліндегі тең және hashCode арасындағы келісім

  1. Егер нысандар әдісті орындау нәтижелері бойынша тең болса equals, онда олар hashcodeбірдей болуы керек.
  2. Егер нысандар әдісті орындау нәтижелері бойынша тең болмаса equals, онда олар hashcodeбірдей немесе әртүрлі болуы мүмкін. Дегенмен, өнімділікті жақсарту үшін әртүрлі нысандардың әртүрлі codeтарды қайтаратыны жақсы.

Java тіліндегі тең әдісті қалай қайта анықтауға болады

  1. @Override
    public boolean equals(Object obj) {
    /*1. Check*/if (obj == this) {
    /*and return */ return true;
             }
  2. Проверьте an object на null, а также проверьте, чтобы an objectы были одного типа. Не делайте проверку с помощью instanceof так How такая проверка будет возвращать true для подклассов и будет работать правильно только в случае если ваш класс объявлен How immutable. Вместо этого можно использовать getClass();

    if (obj == null || obj.getClass() != this.getClass()) {
                return false;
    }
  3. Объявите переменную типа, который вы сравниваете, и приведите obj к этому типу. Потом сравнивайте каждый атрибут типа начиная с численных атрибутов (если имеются) потому что численные атрибуты проверяются быстрей. Сравнивайте атрибуты с помощью операторов И и ИЛИ (так называемые short-circuit logical operators) для объединения проверок с другими атрибутами.

    Person guest = (Person) obj;
            return id == guest.id && (firstName == guest.firstName ||
                (firstName != null && firstName.equals(guest.getFirstName())))
                    && (lastName == guest.lastName || (lastName != null &&                      lastName .equals(guest.getLastName())));
    }
Полный пример переопределения метода equals в Java
/** * Person class with equals and hashcode implementation in Java * @author Javin Paul */
public class Person {
    private int id;
    private String firstName;
    private String lastName;

    public int getId() { return id; }
    public void setId(int id) { this.id = id;}

    public String getFirstName() { return firstName; }
    public void setFirstName(String firstName) { this.firstName = firstName; }
    public String getLastName() { return lastName; }
    public void setLastName(String lastName) { this.lastName = lastName; }
    @Override
    public boolean equals(Object obj) {
    if (obj == this) {
        return true;
    }
    if (obj == null || obj.getClass() != this.getClass()) {
        return false;
    }

    Person guest = (Person) obj;
    return id == guest.id
        && (firstName == guest.firstName
            || (firstName != null &&firstName.equals(guest.getFirstName())))        && (lastName == guest.lastName
            || (lastName != null && lastName .equals(guest.getLastName())
            ));
    }
    @Override
    public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());             result = prime * result + id; result = prime * result +
        ((lastName == null) ? 0 : lastName.hashCode()); return result;
    }
 }

Распространенные ошибки при переопределении equals в Java

  1. Вместо того, чтобы переопределять метод equals (Override) программист перегружает его (Overload)Синтаксис метода equals() в классе Object определен How public boolean equals(Object obj), но многие программисты ненароком перегружают метод: public boolean equals(Person obj) - instead of Object в качестве аргумента используют Name своего класса (напр. Person). Эту ошибку сложно обнаружить из-за static binding. Таким образом, если вы вызовете этот метод для an object своего класса, то метод не просто скомпorруется, а даже сделает это корректно. Однако, если вы положите ваш an object в коллекцию, например ArrayList и вызовете метод contains(), работа которого основана на методе equals(), то метод contains не сможет обнаружить ваш an object.

  2. При переопределении метода equals() не проверять на null переменные, что в конечном итоге заканчивается NullPointerException при вызове equals(). Ниже представлен корректный code.

    firstname == guest.firstname || (firstname != null &&
         firstname.equals(guest.firstname));
  3. Третья распространенная ошибка это не переопределять метод hashCode(), а только equals(). Вы обязаны переопределять оба метода equals() и hashCode() в Java. Метод hashCode используется в hash -коллекциях(например HashSet), и чем меньше будет коллизий (одинаковый code при разных an objectх) тем эффективнее эти коллекции будут работать с an objectми вашего класса.

  4. Последняя распространенная ошибка программистов в том, что при переопределении метода equals() не сохраняется соответствие между методами equals() и compareTo(), что является неформальным требованием для избежания хранения дубликатов в Set (SortedSet, TreeSet).

Подсказки How писать в Java метод equals

  1. Большинство IDE такие How NetBeans, Eclipse и IntelliJ IDEA обеспечивают поддержку генерации методов equals() и hashCode(). В Eclipse нажмите правую кнопку -> source -> generate equals() и hashCode().

  2. Если в классе есть уникальный бизнес-ключ, то будет достаточно сделать проверку только на equalsство этих полей. Как в нашем примере “id” - уникальный номер для каждого Person.

  3. При переопределении hashCode() в Java удостоверьтесь в использовании всех полей, что были использованы в методе equals().

  4. StringIntegerжәне , сияқты орауыш сыныптары Floatжәне Doubleәдісті қайта анықтайды equals(), бірақ StringBufferқайта анықтамайды.

  5. Мүмкіндігінше Java тіліндегі айнымалы мәндерді immutableпайдаланып өрістер жасаңыз.final

  6. StringНысандарды салыстыру кезінде equals()орнына . операторын пайдаланыңыз ==.

  7. Логикалық жағынан тең, бірақ әртүрлі нысандардан жүктелген екі нысан ClassLoaderтең бола алмайды. Есіңізде болсын, жүктеуші класы басқаша болса, тексеру getClass()қайтарылады .false

  8. @OverrideАннотацияны .әдісінде де пайдаланыңыз hashCode, себебі бұл қайтару мәні сияқты нәзік қателерді болдырмайды.Бірақ intкейбір бағдарламашылар қайтарады long.

PS Құрметті әріптестер! Мен бұл мақаланы 21-деңгейдегі есептерді шешуде пайдалы деп таптым! Осы тақырыпты талдауға сәттілік тілеймін, аударманы пайдаланыңыз! Сіз менің рейтингімді көтеруге көмектесесіз деп үміттенемін, өйткені мен қазір бұл форумда пікір қалдыра алмаймын. Барлығына көп рахмет! Түпнұсқа мақала бос уақыттың болмауына байланысты кейбір тармақтарды жіберіп алдым, бірақ 21-деңгейдегі есептерді шешу үшін сізге қажет нәрсені аудардым.
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION