يتم استخدام طريقة متساوية في فئة الكائن لاكتشاف ما إذا كان الكائن يساوي كائنًا آخر. في فئة الكائن ، تحدد هذه الطريقة ما إذا كان كائنين لهما نفس المرجع. إذا كان للكائنين نفس المرجع ، فيجب أن يكونا متساوين. من وجهة النظر هذه ، من المعقول استخدامها كعملية افتراضية. ومع ذلك ، بالنسبة لمعظم الفصول ، هذا الحكم لا معنى له. على سبيل المثال ، لا معنى لها تمامًا مقارنة ما إذا كان اثنان من printstreams متساوية في هذه الطريقة. ومع ذلك ، من الضروري في كثير من الأحيان اكتشاف مساواة حالتين. إذا كانت حالات الكائنين متساوية ، فإن الكائنين يعتبران متساويين. لذلك ، بشكل عام ، يجب إعادة كتابة المقارنات المتساوية في الفصول المخصصة.
فيما يلي بعض الاقتراحات لكتابة طريقة متساوية () مثالية:
(1) تم تسمية المعلمة الصريحة الأخرى ، ويجب تحويلها إلى متغير يسمى آخر لاحقًا
(2) اكتشف ما إذا كان هذا وآخر يشير إلى نفس الكائن:
إذا (هذا == otheroBject) العودة true ؛
هذا البيان هو مجرد تحسين. في الواقع ، هذا شكل يتم تبنيه غالبًا. لأن حساب هذه المعادلة أقل تكلفة بكثير من مقارنة الحقول في الفئة الأولى تلو الأخرى.
(3) تحقق مما إذا كان OtherObject فارغًا ، وإذا كان لاغير ، فالأمر. هذا الاختبار ضروري.
إذا (otheroBject == NULL) إرجاع خطأ ؛
(4) قارن ما إذا كان هذا وآخر ينتمي إلى نفس الفصل. إذا كانت دلالات المتساوية تتغير في كل فئة فرعية ، فاستخدم getClass () للكشف عنها ، والتي تأخذ نفسها كفئة مستهدفة
if (getClass ()! = OtherObject.getClass ()) إرجاع خطأ ؛
إذا كانت جميع الفئات الفرعية لديها نفس الدلالات ، فاستخدم اكتشاف مثيل
إذا (! (مثيل آخر من className))) إرجاع خطأ ؛
(5) تحويل OtherObject إلى متغير من النوع المقابل:
className other = (className) OtherObject ؛
(6) ابدأ الآن في مقارنة جميع المجالات التي تحتاج إلى مقارنة. استخدم == لمقارنة مجال النوع الأساسي ، واستخدام متساوٍ لمقارنة مجال الكائن. إرجاع صحيح إذا كانت جميع الحقول تتطابق ، وإلا عد كاذبة ؛
return field1 == Other.Field1 && field2.equals (other.field2)
إذا تم إعادة تعريف Equals في فئة فرعية ، فيجب عليك تضمين مكالمة Super.equals (أخرى). إذا فشل الكشف ، فمن المستحيل أن تكون متساوية. إذا كانت المجالات الموجودة في الطبقة الفائقة متساوية ، قارن بين مجالات المثيل في الفئة الفرعية.
بالنسبة لحقول نوع الصفيف ، يمكنك استخدام المصفوفات الثابتة.
دعونا نلقي نظرة على بعض أمثلة المقارنة بين الأوتار:
سلسلة A = "ABC" ؛ السلسلة B = "ABC" ؛ سلسلة C = سلسلة جديدة ("ABC") ؛ سلسلة D = سلسلة جديدة ("ABC") ؛ system.out.println (a == b) ؛ // صحيح لأن ثوابت السلسلة تتم مشاركتها في Java ، يوجد فقط نظام نسخة واحد. // false a و c ينتميان إلى كائنين مختلفين system.out.println (A.equals (c)) ؛ // صحيح نظرًا لأن طريقة متساوية في كائن السلسلة تقارن القيم في الكائن ، فإنها تُرجع صحيحًا. (مختلف عن طريقة الكائن المساواة) System.out.println (C == D) ؛ // false على الرغم من أن القيم الموجودة في الكائنات هي نفسها ، إلا أنها تنتمي إلى كائنين مختلفين ، لذلك فهي ليست متساوية System.out.println (c.equals (d)) ؛ // حقيقيببساطة ، عند مقارنة ثوابت السلسلة ، فهو نفس النتيجة التي يتم إرجاعها بواسطة متساوية. عندما تريد مقارنة قيمة كائن السلسلة ، استخدم متساويًا.
انظر مثال على استخدام متساوين:
Package Chapter05.equalstest ؛ استيراد java.util.*؛ الطبقة العامة equalStest {public static void main (string [] args) {exeriese alice1 = new ameiese ("Alice Adams" ، 75000 ، 1987 ، 12 ، 15) ؛ الموظف alice2 = alice1 ؛ // المرجع نفس الكائن الموظف alice3 = موظف جديد ("أليس آدمز" ، 75000 ، 1987 ، 12 ، 15) ؛ الموظف Bob = موظف جديد ("Bob Brandson" ، 50000 ، 1989 ، 10 ، 1) ؛ System.out.println ("alice1 == alice2:" + (alice1 == alice2)) ؛ system.out.println ("alice1 == alice3:" + (alice1 == alice3)) ؛ System.out.println ("alice1.equals (alice3):" + (alice1.equals (alice3))) ؛ System.out.println ("alice1.equals (bob):" + (alice1.equals (bob))) ؛ system.out.println (bob.toString ()) ؛ }} الموظف الفئة {الموظف العام (السلسلة N ، Double S ، int year ، int month ، int day) {name = n ؛ الراتب = s ؛ GregorianCalendar Calendar = Gregoriancalendar الجديد (سنة ، شهر ، يوم) ؛ requeday = calendar.getTime () ؛ } السلسلة العامة getName () {return name ؛ } public double getSalary () {return salary ؛ } التاريخ العام gethireday () {return hireday ؛ } public void raisesalary (double bypercent) {double rise = salary * bypercent / 100 ؛ راتب += رفع ؛ } Override Public Boolean يساوي (ObjectObject) {// اختبارًا سريعًا لمعرفة ما إذا كان يتم تحديد الكائنات إذا كانت (هذا == otherobject) ترجع إلى true ؛ // يجب أن تُرجع كاذبة إذا كانت المعلمة الصريحة لاغية إذا كانت (otheroBject == null) إرجاع False ؛ // إذا لم تتطابق التصنيف ، فلا يمكن أن تكون متساوية إذا كانت (getClass ()! = OtherObject.getClass ()) إرجاع False ؛ // نحن الآن نعلم أن OtherObject هو موظف غير خبيث آخر = (موظف) OtherObject ؛ // اختبار ما إذا كانت الحقول HAVA حددت القيم return name.equals (other.name) && Salary == Other.Salary && hireday.equals (other.hireday) ؛ } Override public int hashcode () {return 7 * name.hashCode () + 11 * New Double (Salary) .HashCode () + 13 * Hireday.HashCode () ؛ } Override public string toString () {return getClass (). getName () + "[name =" + name + "، salary =" + salary + "، hireday =" + hireday + "]" ؛ } اسم السلسلة الخاصة ؛ راتب مزدوج خاص ؛ التاريخ الخاص المستأجر ؛ } مدير الفصل يمتد الموظف {المدير العام (السلسلة n ، double s ، int year ، int month ، int day) {super (n ، s ، year ، month ، day) ؛ bouns = 0 ؛ } Override public double getSalary () {double basesalary = super.getSalary () ؛ إرجاع قواعد + bouns. } public void setBouns (double b) {bouns = b ؛ } Override public boolean يساوي (كائن OSHOBJECT) {if (! super.equals (OtherObject)) return false ؛ مدير آخر = (مدير) OtherObject ؛ // super equals تحقق من أن هذا وغيره ينتمي إلى نفس الفئة عودة bouns == other.bouns ؛ } Override public int hashcode () {return super.hashcode () + 17 * new double (bouns) .hashCode () ؛ } Override public string toString () {return super.toString () + "[bouns =" + bouns + "]" ؛ } نوبات مزدوجة خاصة ؛ } انطلق بشكل أعمق وقم بتقسيمه إلى فئتين وفقًا لـ "ما إذا كان الفصل يتجاوز طريقة متساوية ()".
(1) إذا لم يتجاوز الفئة طريقة متساوية () ، عندما تقارن الكائنين من خلال equals () ، فإنه يقارن ما إذا كان الكائنان هو نفس الكائن. في هذا الوقت ، فإنه يعادل مقارنة هذين الكائنين بواسطة "==".
(2) يمكننا تجاوز طريقة equals () للفئة للسماح متساويًا () مقارنة ما إذا كان كائنين متساويين بطرق أخرى. الممارسة المعتادة هي: إذا كانت محتويات كائنين متساوية ، فإن طريقة متساوية () تُرجع بشكل صحيح ؛ خلاف ذلك ، فإنه يعيد fasle.
بعد ذلك ، دعنا نقدم مثالاً لشرح حالتين أعلاه.
1. حالة "عدم تجاوز طريقة () طريقة"
الرمز كما يلي (equalstest1.java):
استيراد java.util.* ؛ استيراد java.lang.comparable ؛/*** desc equals () برنامج اختبار. */public class equalStest1 {public static void main (string [] args) {// إنشاء كائنات شخصين جديدين بنفس المحتوى ، // استخدم متساويًا لمقارنة ما إذا كان شخص متساوٍ p1 = شخص جديد ("eee" ، 100) ؛ الشخص p2 = شخص جديد ("eee" ، 100) ؛ system.out.printf ("٪ s/n" ، p1.equals (p2)) ؛ } /*** DESC Person Class. */ Private Static Class Person {int Age ؛ اسم السلسلة الشخص العام (اسم السلسلة ، int age) {this.name = name ؛ this.age = العمر ؛ } السلسلة العامة toString () {return name + " -" + Age ؛ }}} نتائج التشغيل:
انسخ الرمز على النحو التالي: خطأ
تحليل النتائج نستخدم p1.equals (p2) لـ "مقارنة ما إذا كانت P1 و P2 متساوية." في الواقع ، تسمى طريقة equals () للكائن. java ، أي (p1 == p2). هو لمقارنة "ما إذا كان P1 و P2 هما نفس الكائن".
من تعريفات P1 و P2 ، يمكننا أن نرى أنه على الرغم من أن محتوىها هو نفسه ، إلا أنهما كائنان مختلفان! لذلك ، فإن نتيجة العودة خاطئة.
2. حالة "الكتابة فوق" طريقة () "
نقوم بتعديل alliendstest1.java أعلاه: تجاوز طريقة متساوية ().
الرمز كما يلي (equalstest2.java):
استيراد java.util.* ؛ استيراد java.lang.comparable ؛/*** desc equals () برنامج اختبار. */الفئة العامة equalStest2 {public static void main (string [] args) {// إنشاء كائنات شخصين جديدين بنفس المحتوى ، // استخدم متساويًا لمقارنة ما إذا كان شخص متساوٍ p1 = شخص جديد ("eee" ، 100) ؛ الشخص p2 = شخص جديد ("eee" ، 100) ؛ system.out.printf ("٪ s/n" ، p1.equals (p2)) ؛ } /*** DESC Person Class. */ Private Static Class Person {int Age ؛ اسم السلسلة الشخص العام (اسم السلسلة ، int age) {this.name = name ؛ this.age = العمر ؛ } السلسلة العامة toString () {return name + " -" + Age ؛ } / *** @desc override equals method* / Override public boolean equals (object obj) {if (obj == null) {return false ؛ } // إذا كان نفس الكائن ، فأرجع إلى حد ما ، وإلا بإرجاع خطأ إذا (this == obj) {return true ؛ }. } شخص = (شخص) obj ؛ return name.equals (person.name) && age == person.age ؛ }}} نتائج التشغيل:
انسخ الرمز على النحو التالي: صحيح
تحليل النتائج:
نقوم بتجاوز وظيفة الشخص المتساوي () في equalstest2.java: عندما يكون اسم وعمر الكائنين على قدم المساواة ، فإنه يعود صحيحًا.
لذلك ، فإن نتيجة التشغيل تعود صحيحة.
بعد قولي هذا ، دعنا نتحدث عن متطلبات جافا للمتساوية (). هناك النقاط التالية:
التماثل: إذا كان X.equals (y) إرجاع "True" ، فيجب أن يعود Y.equals (x) أيضًا "True".
الانعكاس: x.equals (x) يجب أن تعيد "صحيح".
القياس: إذا كانت X.equals (y) تُرجع "true" ، و y.equals (z) إرجاع "true" ، فيجب أن يعود Z.equals (x) أيضًا "True".
الاتساق: إذا كانت X.equals (y) تُرجع "صواب" ، طالما أن محتويات x و y تظل دون تغيير ، بغض النظر عن عدد المرات التي تكرر فيها x.equals (y) ، ستكون العائد "صحيحًا".
غير فارغ ، X.equals (NULL) ، يعيد دائمًا "خطأ" ؛ X.equals (كائنات من أنواع مختلفة و X) تُرجع دائمًا "False".
الآن ، دعنا نراجع دور Equals (): تحديد ما إذا كان كائنين متساويين. عندما نعيد كتابة متساوٍ () ، من المستحيل تغيير وظيفتها!
ما هو الفرق بين متساوين () و ==؟
==: وظيفتها هي تحديد ما إذا كانت عناوين كائنين متساوية. وهذا هو ، حدد ما إذا كان الكائنان هما نفس الكائن.
يساوي (): وظيفتها هي تحديد ما إذا كان كائنين متساوون. ومع ذلك ، فإنه يحتوي بشكل عام على شرطين للاستخدام (تم وصفه بالتفصيل في الجزء السابق 1):
الحالة 1 ، لا يتجاوز الفئة طريقة متساوية (). ثم عند مقارنة كائنين من هذه الفئة من خلال متساوٍ () ، فإنه يعادل مقارنة هذين الكائنين بواسطة "==".
الحالة 2 ، يتجاوز الفئة طريقة متساوية (). بشكل عام ، نقوم بتجاوز طريقة متساوية () لجعل محتويات كائنين متساوية ؛ إذا كانت محتوياتها متساوية ، فإنها تعود بشكل صحيح (أي ، تعتبر الكائنان متساويين).
أدناه ، قارن اختلافاتهم عن طريق الأمثلة.
الرمز كما يلي:
استيراد java.util.* ؛ استيراد java.lang.comparable ؛/*** desc equals () برنامج اختبار. */الفئة العامة equalStest3 {public static void main (string [] args) {// إنشاء كائنات شخصين جديدين بنفس المحتوى ، // استخدم متساويًا لمقارنة ما إذا كان شخص متساوٍ p1 = شخص جديد ("eee" ، 100) ؛ الشخص p2 = شخص جديد ("eee" ، 100) ؛ system.out.printf ("p1.equals (p2): ٪ s/n" ، p1.equals (p2)) ؛ system.out.printf ("p1 == p2: ٪ s/n" ، p1 == p2) ؛ } /*** DESC Person Class. */ Private Static Class Person {int Age ؛ اسم السلسلة الشخص العام (اسم السلسلة ، int age) {this.name = name ؛ this.age = العمر ؛ } السلسلة العامة toString () {return name + " -" + Age ؛ } / *** @desc override equals method* / Override public boolean equals (object obj) {if (obj == null) {return false ؛ } // إذا كان نفس الكائن ، فأرجع إلى حد ما ، وإلا بإرجاع خطأ إذا (this == obj) {return true ؛ }. } شخص = (شخص) obj ؛ return name.equals (person.name) && age == person.age ؛ }}} نتائج التشغيل:
p1.equals (p2): truep1 == p2: false
تحليل النتائج:
على equalstest3.java:
(1) p1.equals (p2)
هذا هو تحديد ما إذا كانت محتويات P1 و P2 متساوية. لأن الشخص يتغلب على طريقة () ، ويتم استخدام هذا يساوي () لتحديد ما إذا كانت محتويات P1 و P2 متساوية ، بالضبط محتويات P1 و P2 متساوية ؛ لذلك ، العودة صحيح.
(2) P1 == P2
هذا هو تحديد ما إذا كان P1 و P2 هما نفس الكائن. لأنهما شخصان جديدان لكل منهما ؛ لذلك ، العودة كاذبة.