JavaRush /Java blogi /Random-UZ /Java'da teng() va hashCode() usullarini ortiqcha yuklash
Coder
Daraja

Java'da teng() va hashCode() usullarini ortiqcha yuklash

Guruhda nashr etilgan

Java'da equals() va hashCode() usullarini bekor qilish

Equalsva hashCodeular sinfda e'lon qilingan Objectva standart Java kutubxonalarida mavjud bo'lgan asosiy usullardir. Java'da equals() va hashCode() usullarini ortiqcha yuklash - 1Usul ob'ektlarni solishtirish va ob'ekt uchun butun son kodini yaratish uchun еquals()ishlatiladi . hashCodeUshbu usullar Java standart kutubxonalarida ob'ektlarni kiritish va olishda keng qo'llaniladi HashMap. Usul, shuningdek, boshqa ilovalarda, shuningdek, ob'ektlarni solishtirish kerak bo'lgan boshqa holatlarda equalfaqat noyob ob'ektlar saqlanishini ta'minlash uchun ishlatiladi . Sinfdagi usulning sukut bo'yicha amalga oshirilishi o'zgaruvchilar saqlaydigan xotira manzillariga havolalarni solishtiradi va manzillar mos kelsagina qaytaradi, boshqacha qilib aytganda, o'zgaruvchilar bir xil ob'ektga murojaat qiladi. Agar taqqoslash tabiiy mantiq yoki biznes mantiqiga muvofiq amalga oshirilishini kutsangiz, Java va usullarini bekor qilishni tavsiya qiladi. Standart Java kutubxonalaridagi ko'pgina sinflar ularni bekor qiladi, masalan, sinf o'z o'rnini bosadi , shuning uchun solishtirilayotgan ikkita ob'ektning mazmuni bir xil bo'lsa, u qaytib keladi. O'rash sinfi raqamli taqqoslashni amalga oshirish usulini bekor qiladi va hokazo. Java ularning va ni solishtirish usullariga ham tayanganligi sababli , Java ushbu usullarni bekor qilish uchun quyidagi qoidalarni taklif qiladi: HashSetSetequals()java.lang.Objecttrueequals()hashCode()StringequalstrueIntegerequalHashMapHashTableequals()hashCode()keyvalues
  1. Reflektorlik: ob'ekt o'ziga teng bo'lishi kerak.
  2. Simmetrik: agar a.equals(b)u qaytsa true, b.equals(a)u ham qaytishi kerak true.
  3. Tranzitivlik: agar a.equals(b)u qaytsa trueva b.equals(c)yana qaytarsa true, c.equals(a)u ham qaytishi kerak true.
  4. Muvofiqlik: Usulga takroriy qo'ng'iroqlar, equals()ob'ektning ba'zi xususiyat qiymatlari o'zgarmas ekan, bir xil qiymatni qaytarishi kerak. Ya'ni, agar Java-da ikkita ob'ekt teng bo'lsa, ularning xususiyatlari o'zgarmas ekan, ular teng bo'ladi.
  5. Taqqoslash null: ob'ektni tekshirish kerak null. Agar ob'ekt ga teng bo'lsa null, u holda usul falseemas, balki qaytishi kerak NullPointerException. Masalan, a.equals(null)u qaytishi kerak false.

Java'da tenglar va hashCode o'rtasidagi kelishuv

  1. Agar ob'ektlar usulni bajarish natijalarida teng bo'lsa equals, ular hashcodebir xil bo'lishi kerak.
  2. Agar ob'ektlar usulni bajarish natijalarida teng bo'lmasa equals, ular hashcodebir xil yoki boshqacha bo'lishi mumkin. Biroq, ishlashni yaxshilash uchun turli ob'ektlar turli xil kodlarni qaytarishi yaxshiroqdir.

Java'da teng usulini qanday bekor qilish mumkin

  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. Stringva kabi oʻrash sinflari Integerva usulini bekor qiladi Float, lekin bekor qilmaydi.Doubleequals()StringBuffer

  5. Iloji bo'lsa, Java-da o'zgaruvchilardan immutablefoydalanib, maydonlarni yarating final.

  6. StringOb'ektlarni taqqoslashda equals(). operatoridan foydalaning ==.

  7. Mantiqiy jihatdan teng bo'lgan, lekin turli ob'ektlardan yuklangan ikkita ob'ekt ClassLoaderteng bo'lishi mumkin emas. Esda tutingki, agar yuklovchi sinfi boshqacha bo'lsa, bilan tekshirish getClass()qaytadi .false

  8. @OverrideIzohdan . usulida ham foydalaning hashCode, chunki bu ning qaytarilish qiymati kabi nozik xatolarning oldini oladi intBiroq, ba'zi dasturchilar qaytadi long.

PS Hurmatli hamkasblar! Men ushbu maqolani 21-darajali muammolarni hal qilishda foydali deb topdim! Ushbu mavzuni tahlil qilishda omad tilayman, tarjimadan foydalaning! Umid qilamanki, siz mening reytingimni oshirishga yordam berasiz, chunki hozir men ushbu forumda sharh qoldira olmayman. Hammaga katta rahmat! Asl maqola bo'sh vaqtim yo'qligi sababli ba'zi fikrlarni o'tkazib yubordim, lekin 21-darajali muammolarni hal qilish uchun bilishingiz kerak bo'lgan hamma narsani tarjima qildim.
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION