سؤال

ركضت مثيرة للاهتمام (و محبطة جدا) المسألة مع equals() طريقة اليوم والتي تسبب ما ظننت أن يكون اختبار جيد فئة إلى تحطم سبب الخلل الذي أخذ مني وقت طويل جدا لتعقب.

فقط للتأكد من اكتمالها ، لم أكن باستخدام IDE أو المصحح - فقط جيدة القديمة الطراز محرر نصوص النظام.خارج هناك.الوقت محدود جدا و كان مشروع المدرسة.

على أية حال -

كنت النامية الأساسية عربة التسوق التي يمكن أن تحتوي على ArrayList من Book الكائنات.من أجل تنفيذ addBook(), removeBook(), ، hasBook() أساليب العربة ، أردت أن تحقق إذا كان Book موجودة بالفعل في Cart.لذا أذهب -

public boolean equals(Book b) {
    ... // More code here - null checks
    if (b.getID() == this.getID()) return true;
    else return false;
}

كل شيء يعمل بشكل جيد في الاختبار.لقد خلق 6 كائنات و ملء لهم مع البيانات.القيام بالعديد من يضيف أو يزيل قد() العمليات على Cart و كل شيء يعمل بشكل جيد.قرأت أنه يمكنك إما equals(TYPE var) أو equals(Object o) { (CAST) var } ولكن يفترض أنه منذ كان يعمل ، لا يهم كثيرا.

ثم واجهت مشكلة - أنا في حاجة إلى إنشاء Book كائن مع فقط على ID في ذلك من داخل الطبقة الكتاب.أي بيانات أخرى سيكون دخل في ذلك.أساسا ما يلي:

public boolean hasBook(int i) {
    Book b = new Book(i);
    return hasBook(b);
}

public boolean hasBook(Book b) {
    // .. more code here
    return this.books.contains(b);
}

فجأة ، equals(Book b) الطريقة لم تعد تعمل.استغرق هذا وقتا طويلا جدا لتعقب بدون المصحح وعلى افتراض Cart كانت الطبقة واختبارها بشكل صحيح و الصحيح.بعد swaapping على equals() الطريقة التالية:

public boolean equals(Object o) {
    Book b = (Book) o;
    ... // The rest goes here   
}

كل شيء بدأ العمل مرة أخرى.هل هناك سبب الأسلوب قررت عدم اتخاذ كتاب المعلمة على الرغم من أنه من الواضح كان a Book الكائن ؟ الفرق الوحيد يبدو أن ذلك كان إنشاء مثيل من داخل نفس الطبقة ، فقط شغل مع واحد بيانات الأعضاء.أنا في حيرة من أمري.رجاء تسليط بعض الضوء ؟

هل كانت مفيدة؟

المحلول

في جافا ، equals() الطريقة الموروثة من Object هو:

public boolean equals(Object other);

وبعبارة أخرى ، يجب أن تكون المعلمة من نوع Object.

على ArrayList يستخدم الصحيح يساوي الأسلوب حيث كنت دائما الدعوة التي لم تجاوز بشكل صحيح Object's يساوي.

لا تجاوز الأسلوب بشكل صحيح يمكن أن يسبب مشاكل.

لقد تجاوز يساوي التالية في كل مرة:

@Override
public boolean equals(Object other){
    if (other == null) return false;
    if (other == this) return true;
    if (!(other instanceof MyClass))return false;
    MyClass otherMyClass = (MyClass)other;
    ...test other properties here...
}

استخدام @Override الشرح يمكن أن تساعد طن مع أخطاء سخيفة.

استخدامها كلما كنت تعتقد أنك تجاوز سوبر فئة' أو واجهة الأسلوب.بهذه الطريقة, إذا كنت تفعل ذلك الخطأ سوف تحصل على خطأ ترجمة.

نصائح أخرى

إذا كنت تستخدم الكسوف فقط إذهب إلى أعلى القائمة

المصدر --> توليد يساوي() ، hashCode()

قليلا خارج الموضوع على سؤالك, لكنه ربما الجدير بالذكر على كل حال:

المشاع لانج وقد حصلت على بعض الأساليب التي يمكنك استخدامها في الغالب يساوي hashcode.تحقق من EqualsBuilder.reflectionEquals(...) و HashCodeBuilder.reflectionHashCode(...).حفظ لي الكثير من الصداع في الماضي - على الرغم من وبطبيعة الحال إذا كنت فقط تريد أن تفعل "يساوي" على الهوية قد لا تناسب الظروف الخاصة بك.

كما توافق على أنك يجب أن تستخدم @Override الشرح كلما كنت الغالبة يساوي (أو أي طريقة أخرى).

آخر حل سريع ينقذ رمز المتداول هو لومبوك EqualsAndHashCode الشرح.فمن السهل, أنيقة وقابلة للتخصيص.و لا يعتمد على IDE.على سبيل المثال ؛

import lombok.EqualsAndHashCode;

@EqualsAndHashCode(of={"errorNumber","messageCode"}) // Will only use this fields to generate equals.
public class ErrorMessage{

    private long        errorNumber;
    private int         numberOfParameters;
    private Level       loggingLevel;
    private String      messageCode;

ترى خيارات قارئي إلى تخصيص الحقول التي تستخدم في يساوي.لومبوك هي robert: روبرت في مخضرم.فقط إضافة مع المقدمة نطاق:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.14.8</version>
    <scope>provided</scope>
</dependency>

في Android Studio هو alt + insert ---> يساوي و hashCode

على سبيل المثال:

    @Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Proveedor proveedor = (Proveedor) o;

    return getId() == proveedor.getId();

}

@Override
public int hashCode() {
    return getId();
}

النظر:

Object obj = new Book();
obj.equals("hi");
// Oh noes! What happens now? Can't call it with a String that isn't a Book...

على instanceOf بيان غالبا ما تستخدم في تنفيذ يساوي.

هذا هو شعبية شرك !

المشكلة هي أن استخدام instanceOf ينتهك سيادة التماثل:

(object1.equals(object2) == true) إذا وفقط إذا (object2.equals(object1))

إذا كان الأول يساوي صحيح ، object2 مثيل من فئة فرعية من الطبقة حيث obj1 ينتمي إلى ، ثم الثانية يساوي سوف return false!

إذا كان ينظر إلى الصف حيث ob1 ينتمي أعلن النهائي ، ثم هذا المشكلة لا يمكن أن تنشأ ، ولكن بشكل عام ، يجب أن الاختبار على النحو التالي:

this.getClass() != otherObject.getClass(); إذا لم يكن كذلك ، return false, وإلا الاختبار الحقول مقارنة المساواة!

recordId هو العقار الكائن

@Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Nai_record other = (Nai_record) obj;
        if (recordId == null) {
            if (other.recordId != null)
                return false;
        } else if (!recordId.equals(other.recordId))
            return false;
        return true;
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top