سؤال

هذا السؤال يرتبط تحديدا تجاوز يساوي() طريقة الكائنات مع عدد كبير من المجالات.أولا اسمحوا لي أن أقول أن هذا كائن كبير لا يمكن تقسيمها إلى مكونات متعددة دون انتهاك OO المبادئ حتى تقول لي "لا فئة يجب أن يكون أكثر من x حقول" لن يساعد.

تتحرك على المشكلة أتى ثماره عندما نسيت أن تحقق أحد الحقول من أجل المساواة.لا يساوي الطريقة غير صحيحة.ثم فكرت في استخدام التفكير:

--code removed because it was too distracting--

الغرض من هذا المنصب ليس بالضرورة أن ريفاكتور رمز (هذا ليس كود أنا باستخدام), ولكن بدلا من ذلك الحصول على مدخلات بشأن ما إذا كان أو لم يكن هذا هو فكرة جيدة.

الايجابيات:

  • إذا كان حقل جديد يضاف ، فإنه يتم تلقائيا تضمين
  • الأسلوب هو أكثر مقتضب من 30 إذا البيانات

سلبيات:

  • إذا كان حقل جديد يضاف ، فإنه يتم تلقائيا تضمين بعض الأحيان وهذا أمر غير مرغوب فيه
  • الأداء:هذا قد يكون أبطأ, أنا لا أشعر بحاجة إلى الخروج التعريف
  • القائمة البيضاء مجالات معينة تجاهل في المقارنة قبيحة قليلا

أي أفكار ؟

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

المحلول

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

P. S.إذا كنت تذهب في هذا الطريق equals(), لا تنسى أن تفعل شيئا مماثل hashCode().

P. P. S.وأنا على ثقة أنك نظرت بالفعل HashCodeBuilder و EqualsBuilder.

نصائح أخرى

استخدام الكسوف ، FFS!

حذف hashCode و يساوي أساليب لديك.

انقر بزر الماوس الأيمن على الملف.

حدد المصدر->إنشاء hashcode و يساوي...

فعلت!لا مزيد من المخاوف حول انعكاس.

كرر لكل مجال وأضاف, يمكنك فقط استخدام عرض المخطط التفصيلي حذف طريقتين ، ومن ثم السماح الكسوف يقدم لهم.

إذا كنت لا تذهب انعكاس النهج ، EqualsBuilder لا يزال صديقك:

 public boolean equals(Object obj) {
    return EqualsBuilder.reflectionEquals(this, obj);
 }

وهنا فكر إذا كنت قلقا حول:

1/ أن ننسى لتحديث سلسلة كبيرة من إذا-بيانات التحقق من المساواة عند إضافة/إزالة حقل.

2/ أداء نفعل هذا يساوي (طريقة).

جرب ما يلي:

a/ العودة إلى استخدام سلسلة طويلة من إذا-البيانات الخاصة بك يساوي (طريقة).

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

ج/ في المنشئ الخاص بك لهذا الكائن ، متزامنة التشغيل بمجرد استدعاء هذه الدالة (على غرار نمط المفرد).وبعبارة أخرى, إذا كان هذا هو أول كائن شيدت من قبل هذه الفئة ، استدعاء وظيفة التدقيق المذكورة في الفقرة (ب) أعلاه.

استثناء سوف تجعل من الواضح على الفور عند تشغيل البرنامج الخاص بك إذا كنت لم تقم بتحديث الخاص بك إذا-بيانات تطابق ينعكس المجالات ؛ ثم يمكنك إصلاح إذا-البيانات وتحديث قائمة الحقول من (ب) أعلاه.

اللاحقة بناء الأجسام لا تفعل هذا الاختيار الخاص بك يساوي() طريقة تشغيل كما هو في أقصى سرعة ممكنة.

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

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

يمكنك دائما علق مجالات تفعل/لا تريد الخاص بك يساوي الطريقة التي ينبغي أن تكون واضحة وبسيطة لتغيير ذلك.

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

أيضا بالحديث عن تجزئة الخرائط لديك نفس المشكلة مع hashCode الأسلوب.

أخيرا, هل حقا بحاجة لمقارنة جميع المجالات من أجل المساواة ؟

لديك بعض الأخطاء في التعليمات البرمجية الخاصة بك.

  1. لا يمكنك أن تفترض أن this و obj هي نفس الطبقة.في الواقع, انها صراحة سمحت obj إلى أي فئة أخرى.هل يمكن أن تبدأ مع if ( ! obj instanceof myClass ) return false; ومع ذلك هذا هو لا تزال غير صحيح لأن obj يمكن أن تكون مجموعة فرعية من this مع حقول إضافية قد يهم.
  2. عليك أن الدعم null القيم obj مع بسيطة if ( obj == null ) return false;
  3. لا يمكنك علاج null و سلسلة فارغة على قدم المساواة.بدلا علاج null خصيصا.أبسط طريقة هنا هو أن تبدأ بمقارنة Field.get(obj) == Field.get(this).إذا كانت تساوي أو كليهما يحدث للإشارة إلى نفس الكائن ، هذا هو سريع.(ملاحظة:وهذا أيضا هو الأمثل ، والتي تحتاج لأن هذا هو بطء الروتين.) إذا فشل هذا ، يمكنك استخدام سريع if ( Field.get(obj) == null || Field.get(this) == null ) return false; للتعامل مع الحالات التي تكون فيها واحد بالضبط هو null.أخيرا يمكنك استخدام المعتاد equals().
  4. كنت لا تستخدم foundMismatch

أنا أتفق مع أن هانك [HashCodeBuilder][1] و [EqualsBuilder][2] هو أفضل وسيلة للذهاب.فإنه من السهل للحفاظ على الكثير من رمز المتداول ، يمكنك تجنب كل هذه القضايا.

هل يمكن استخدام التعليقات التوضيحية إلى استبعاد الحقول من التحقق

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

@IgnoreEquals
String fieldThatShouldNotBeCompared;

ثم بالطبع يمكنك التحقق من وجود هذا الشرح في عام يساوي الأسلوب.

إذا كان لديك الوصول إلى أسماء الحقول ، لماذا لا تجعل معيار الحقول التي لا تريد أن تدرج تبدأ دائما مع "المحلية" أو "nochk" أو شيء من هذا القبيل.

ثم القائمة السوداء جميع الحقول التي تبدأ مع هذه (المدونة ليست قبيحة جدا ثم).

لا شك انها أبطأ قليلا.عليك أن تقرر ما إذا كنت ترغب في مبادلة سهولة التحديثات ضد سرعة التنفيذ.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top