JavaRush /Blog Java /Random-MS /Lebihan beban sama dengan() dan kaedah hashCode() dalam J...
Coder
Tahap

Lebihan beban sama dengan() dan kaedah hashCode() dalam Java

Diterbitkan dalam kumpulan

Mengatasi kaedah equals() dan hashCode() dalam Java

Equalsdan hashCodemerupakan kaedah asas yang diisytiharkan dalam kelas Objectdan terkandung dalam perpustakaan Java standard. Kaedah overloading equals() dan hashCode() dalam Java - 1Kaedah ini еquals()digunakan untuk membandingkan objek dan hashCodemenghasilkan kod integer untuk objek tersebut. Kaedah ini digunakan secara meluas dalam perpustakaan standard Java apabila memasukkan dan mendapatkan semula objek dalam HashMap. Kaedah ini equaljuga digunakan untuk memastikan bahawa hanya objek unik disimpan dalam pelaksanaan HashSetlain Set, serta dalam mana-mana kes lain di mana objek perlu dibandingkan. Pelaksanaan lalai kaedah equals()dalam kelas java.lang.Objectmembandingkan rujukan kepada alamat memori yang disimpan oleh pembolehubah dan dikembalikan truehanya jika alamat sepadan, dengan kata lain, pembolehubah merujuk kepada objek yang sama. Java mengesyorkan mengatasi kaedah equals()dan hashCode()jika anda menjangkakan perbandingan dilakukan mengikut logik semula jadi atau logik perniagaan. Banyak kelas dalam perpustakaan Java standard mengatasinya, contohnya kelas Stringmenimpa equalssupaya ia kembali truejika kandungan dua objek yang dibandingkan adalah sama. Kelas pembalut mengatasi Integerkaedah equaluntuk melakukan perbandingan berangka, dan seterusnya. Memandangkan Java HashMapjuga bergantung pada dan kaedah untuk membandingkan dan , Java menawarkan peraturan berikut untuk mengatasi kaedah ini: HashTableequals()hashCode()keyvalues
  1. Reflekstiviti: Objek mestilah sama dengan dirinya sendiri.
  2. Simetri: jika a.equals(b)ia kembali true, maka b.equals(a)ia juga mesti kembali true.
  3. Transitiviti: jika a.equals(b)ia kembali truedan b.equals(c)juga kembali true, maka c.equals(a)ia juga mesti kembali true.
  4. Ketekalan: Panggilan berulang kepada kaedah equals()mesti mengembalikan nilai yang sama selagi beberapa nilai sifat objek tidak diubah. Iaitu, jika dua objek sama di Jawa, maka ia akan sama selagi sifatnya tidak berubah.
  5. Perbandingan null: Objek mesti diperiksa untuk null. Jika objek adalah sama dengan null, maka kaedah harus kembali false, bukan NullPointerException. Sebagai contoh, a.equals(null)ia harus kembali false.

Perjanjian antara equals dan hashCode dalam Java

  1. Jika objek adalah sama dalam hasil pelaksanaan kaedah equals, maka ia hashcodemestilah sama.
  2. Jika objek tidak sama dalam hasil pelaksanaan kaedah equals, maka ia hashcodeboleh sama ada sama atau berbeza. Walau bagaimanapun, untuk meningkatkan prestasi, adalah lebih baik untuk mempunyai objek yang berbeza mengembalikan kod yang berbeza.

Bagaimana untuk menimpa kaedah sama di Jawa

  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. Stringdan kelas pembalut seperti Integer, Floatdan Doublemengatasi kaedah equals(), tetapi StringBuffertidak mengatasi.

  5. Apabila boleh, buat medan immutablemenggunakan finalpembolehubah dalam Java.

  6. Apabila membandingkan Stringobjek, gunakan equals()operator . sebaliknya ==.

  7. Dua objek yang secara logiknya sama tetapi dimuatkan daripada objek yang berbeza ClassLoadertidak boleh sama. Ingat bahawa menyemak dengan getClass()akan kembali falsejika kelas pemuat adalah berbeza.

  8. Gunakan @Overrideanotasi juga pada kaedah . hashCode, kerana ini menghalang ralat halus seperti nilai pulangan int. Walau bagaimanapun, sesetengah pengaturcara mengembalikan long.

PS Rakan sekerja yang dihormati! Saya dapati artikel ini berguna dalam menyelesaikan masalah tahap 21! Saya berharap anda berjaya dalam menganalisis topik ini, gunakan terjemahan! Saya berharap anda akan membantu saya meningkatkan rating saya, kerana sekarang saya tidak boleh meninggalkan komen di forum ini. Terima kasih banyak, semua orang! Artikel asal Saya meninggalkan beberapa mata kerana kekurangan masa lapang, tetapi saya menterjemah semua yang anda perlu tahu untuk menyelesaikan masalah tahap 21.
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION