JavaRush /مدونة جافا /Random-AR /التحميل الزائد يساوي () وأساليب hashCode () في Java
Coder
مستوى

التحميل الزائد يساوي () وأساليب hashCode () في Java

نشرت في المجموعة

تجاوز أساليب يساوي () و hashCode () في جافا

Equalsوهي hashCodeالطرق الأساسية المعلنة في الفصل Objectوالمضمنة في مكتبات Java القياسية. التحميل الزائد يساوي () وأساليب hashCode () في Java - 1يتم استخدام الأسلوب еquals()لمقارنة الكائنات وإنشاء hashCodeرمز عدد صحيح للكائن. تُستخدم هذه الأساليب على نطاق واسع في مكتبات Java القياسية عند إدراج الكائنات واسترجاعها في ملفات HashMap. تُستخدم هذه الطريقة equalأيضًا لضمان تخزين الكائنات الفريدة فقط في التطبيقات HashSetالأخرى Set، وكذلك في أي حالات أخرى تحتاج فيها الكائنات إلى المقارنة. يقارن التنفيذ الافتراضي للطريقة equals()في الفصل المراجع java.lang.Objectبعناوين الذاكرة التي تخزنها المتغيرات ويعيدها trueفقط إذا كانت العناوين متطابقة، بمعنى آخر، تشير المتغيرات إلى نفس الكائن. توصي Java بتجاوز الأساليب " equals()و" hashCode()إذا كنت تتوقع إجراء المقارنة وفقًا للمنطق الطبيعي أو منطق الأعمال. تتجاوزها العديد من الفئات في مكتبات Java القياسية، على سبيل المثال، Stringتتجاوز الفئة equalsبحيث يتم إرجاعها trueإذا كانت محتويات الكائنين اللذين تتم مقارنتهما متماثلين. تتجاوز فئة المجمع Integerطريقة equalإجراء مقارنة رقمية، وما إلى ذلك. نظرًا لأن Java تعتمد HashMapأيضًا على طرق للمقارنة بين و ، فإن Java تقدم القواعد التالية لتجاوز هذه الطرق: HashTableequals()hashCode()keyvalues
  1. الانعكاسية: يجب أن يكون الجسم مساوياً لنفسه.
  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: يجب التحقق من الكائن null. إذا كان الكائن يساوي null، فيجب أن ترجع الطريقة false، وليس NullPointerException. على سبيل المثال، a.equals(null)يجب أن يعود false.

اتفاق بين يساوي و hashCode في جافا

  1. إذا كانت الكائنات متساوية في نتائج تنفيذ الطريقة equals، hashcodeفيجب أن تكون هي نفسها.
  2. إذا لم تكن الكائنات متساوية في نتائج تنفيذ الطريقة equals، فيمكن hashcodeأن تكون متماثلة أو مختلفة. ومع ذلك، لتحسين الأداء، من الأفضل أن تقوم كائنات مختلفة بإرجاع رموز مختلفة.

كيفية تجاوز طريقة يساوي في جافا

  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. Stringوفئات المجمعة مثل Integer، Floatوتجاوز Doubleالطريقة equals()، ولكنها StringBufferلا تتجاوز.

  5. كلما أمكن، قم بإنشاء الحقول immutableباستخدام finalالمتغيرات في Java.

  6. عند مقارنة Stringالكائنات، استخدم equals()عامل التشغيل . بدلاً من ذلك ==.

  7. لا يمكن أن يكون كائنان متساويان منطقيًا ولكن تم تحميلهما من كائنين مختلفين ClassLoaderمتساويين. تذكر أن التحقق من ذلك getClass()سيعود falseإذا كانت فئة المُحمل مختلفة.

  8. استخدم @Overrideالتعليق التوضيحي أيضًا في الطريقة hashCode.، لأن هذا يمنع الأخطاء الدقيقة مثل القيمة المرجعة لـ int. ومع ذلك، يقوم بعض المبرمجين بإرجاع long.

ملاحظة: زملائي الأعزاء! لقد وجدت هذه المقالة مفيدة في حل مشاكل المستوى 21! أتمنى لك حظا سعيدا في تحليل هذا الموضوع، استخدم الترجمة! آمل أن تساعدوني في رفع تقييمي، لأنني الآن لا أستطيع حتى ترك تعليق في هذا المنتدى. شكرا جزيلا للجميع! المقالة الأصلية حذفت بعض النقاط بسبب عدم وجود وقت فراغ، لكني قمت بترجمة كل ما تحتاج إلى معرفته لحل مشاكل المستوى 21.
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION