JavaRush /Java блогу /Random-KY /Java'да equals() жана hashCode() ыкмаларын ашыкча жүктөө
Coder
Деңгээл

Java'да equals() жана hashCode() ыкмаларын ашыкча жүктөө

Группада жарыяланган

Java'дагы equals() жана hashCode() ыкмаларын жокко чыгаруу

Equalsжана hashCodeкласста жарыяланган Objectжана стандарттуу Java китепканаларында камтылган негизги методдор. Java'да equals() жана hashCode() ыкмаларын ашыкча жүктөө - 1Метод an objectтерди салыштыруу жана an object үчүн бүтүн codeду түзүү үчүн еquals()колдонулат . hashCodeБул ыкмалар Java стандарттык китепканаларында an objectтерди киргизүүдө жана алууда кеңири колдонулат HashMap. Метод ошондой эле башка ишке ашырууларда, ошондой эле an objectтерди салыштыруу керек болгон башка учурларда equalгана уникалдуу an objectтер сакталышын камсыз кылуу үчүн колдонулат . Методдун класстагы демейки ишке ашырылышы өзгөрмөлөр сактаган эстутум даректерине шилтемелерди салыштырат жана даректер дал келген учурда гана кайтарат, башкача айтканда, өзгөрмөлөр бир эле an objectке кайрылат. Салыштыруу табигый логикага же бизнес логикасына ылайык жасалышын күтсөңүз, Java жана методдорун жокко чыгарууну сунуштайт. Стандарттык Java китепканаларындагы көптөгөн класстар аларды жокко чыгарат, мисалы класс, салыштырылып жаткан эки an objectтин мазмуну бирдей болсо, ал кайтып келгидей кылып жокко чыгарат . Ороочу классы сандык салыштырууну жүргүзүү ыкмасын жокко чыгарат жана башкалар. Java да алардын жана менен салыштыруу ыкмаларына таянгандыктан , Java бул ыкмаларды жокко чыгаруу үчүн төмөнкү эрежелерди сунуштайт: HashSetSetequals()java.lang.Objecttrueequals()hashCode()StringequalstrueIntegerequalHashMapHashTableequals()hashCode()keyvalues
  1. Reflexivity: 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()an objectтин кээ бир менчик баалуулуктары өзгөртүлбөсө, ошол эле маанини кайтарышы керек. Башкача айтканда, Java тorнде эки an object бирдей болсо, анда алардын касиеттери өзгөрүүсүз калганда, алар бирдей болот.
  5. Салыштыруу null: an object текшерorши керек null. Эгерде an object ге барабар болсо null, анда метод falseэмес, кайтып келиши керек NullPointerException. Мисалы, a.equals(null)ал кайтып келиши керек false.

Java тorндеги тең жана hashCode ортосундагы макулдашуу

  1. Эгерде an objectтер методдун аткарылышынын жыйынтыгы боюнча бирдей болсо equals, анда алар hashcodeбирдей болушу керек.
  2. Эгерде an objectтер методдун аткарылышынын жыйынтыгы боюнча бирдей болбосо equals, анда алар hashcodeбирдей же ар башка болушу мүмкүн. Бирок, ишти жакшыртуу үчүн, ар кандай an objectтер ар кандай 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жокко чыгарbyte.

  5. Мүмкүн болушунча Java'да өзгөрмөлөрдү immutableколдонуп талааларды түзүңүз.final

  6. StringОбъекттерди салыштырганда , equals()анын ордуна . операторун колдонуңуз ==.

  7. Логикалык жактан бирдей, бирок ар башка an objectтерден жүктөлгөн эки an object ClassLoaderбирдей боло алbyte. Эгер жүктөгүч классы башка болсо, текшерүү getClass()кайтып келерин унутпаңыз.false

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

PS Урматтуу кесиптештер! Мен бул макаланы 21-деңгээлдеги маселелерди чечүүдө пайдалуу деп таптым! Бул теманы талдоодо ийгorк каалайм, котормодон пайдалангыла! Сиз менин рейтингимди көтөрүүгө жардам бересиз деп үмүттөнөм, анткени азыр мен бул форумга комментарий калтыра албайм. Баарына чоң рахмат! Оригиналдуу макала Бош убактымдын жетишсиздигинен кээ бир пункттарды калтырып койдум, бирок 21-деңгээлдеги маселелерди чечүү үчүн сизге керектүү нерселердин баарын котордум.
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION