مقارنة الشخصية، عدد صحيح وأنواع مماثلة في Java: استخدم المساواة أو ==؟

StackOverflow https://stackoverflow.com/questions/735832

  •  09-09-2019
  •  | 
  •  

سؤال

أردت أن أتأكد من شيء ما في جافا: إذا كان لدي حرف أو عدد صحيح أو طويل من الأشياء، يجب أن أستخدم المساواة أو هو == كافية؟

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

الحدس الخاص بي هو استخدام المساواة، لكنني أريد أن أتأكد من أنني لا أهدر الأداء.

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

المحلول

تحرير: يجعل المواصفات بعض ضمانات لتحويل الملاكمة. من القسم 5.1.7.:

إذا كانت القيمة P أن تكون محاصرات صحيحة أو كاذبة أو بايت، فاجرا في نطاق النطاق u007 إلى u007f، أو عدد int أو قصير بين -128 و 127، ثم دع R1 و R2 تكون نتائج أي تحويلين للملاكمة من ص. هو الحال دائما أن R1 == R2.

التطبيق يمكن استخدام تجمع أكبر، مانع لك.

أود حقا تجنب كتابة التعليمات البرمجية التي تعتمد ذلك على ذلك. ليس لأنه قد يفشل، ولكن لأنه ليس واضحا - سيعرف عدد قليل من الناس المواصفات جيدا. (اعتقدت سابقا أنه كان يعتمد على التنفيذ.)

يجب عليك استخدامها equals أو مقارنة القيم الأساسية، أي

if (foo.equals(bar))

أو

if (foo.intValue() == bar.intValue())

لاحظ أنه حتى إذا تم ضمان الاستهلاابي استخدام القيم الثابتة، فيمكن للمتصلين الآخرين دائما إنشاء مثيلات منفصلة على أي حال.

نصائح أخرى

إذا كنت ترغب في مقارنة أي شيء عن قيمة أي كائن، استخدم .equals().

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

"=="فقط يقارن فقط هوية الكائن وأنت ذلك نادرا جدا، ما تريد. و de-facto أبدا ما تريد مع الأغلفة البدائية.

فقط استخدم == في واحدة من هذين السيناريوهات:

  1. جميع القيم المشاركة في المقارنة أنواع بدائية (ويفضل أن لا تظهر أرقام النقطة العائمة)
  2. تريد حقا معرفة ما إذا كانت المراجع تشير إلى نفس الكائن (يتضمن ذلك مقارنة enumS، لأنه هناك القيمة مرتبطة بهوية الكائن)
//Quick test
public class Test {
  public static void main(String[] args) {
    System.out.println("Are they equal? "+ (new Long(5) == new Long(5)));
  }
}

انتاج:

"هل هم متساوون؟ 0"

إجابه:

لا، انهم ليسوا متساوين. يجب عليك استخدام. المساواة أو مقارنة القيم البدائية الخاصة بهم.

Java لغة المواصفات 5.1.7:

إذا كانت القيمة P أن تكون محاصرات صحيحة أو كاذبة أو بايت، فاجرا في نطاق النطاق u007 إلى u007f، أو عدد int أو قصير بين -128 و 127، ثم دع R1 و R2 تكون نتائج أي تحويلين للملاكمة من ص. هو الحال دائما أن R1 == R2.

و:

مناقشة

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

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

هذا يضمن أنه في معظم الحالات الشائعة، سيكون السلوك هو المرغوب فيه، دون فرض عقوبة أداء لا مبرر لها، خاصة على الأجهزة الصغيرة. قد تكون تطبيقات أقل محدودة الذاكرة، على سبيل المثال، ذاكرة التخزين المؤقت لجميع الشخصيات والسروال، وكذلك الأعداد الصحيحة والأسود في نطاق -32k - + 32K.

لذلك، في بعض الحالات == سيعمل، في كثير من الآخرين لن يفعل ذلك. استخدم دائما. المساواة لتكون آمنا لأنك لا تستطيع المسلمين (بشكل عام) كيف تم الحصول على المثبتات.

إذا كانت السرعة عاملا (أكثر من اللازم، تبدأ من خلال مقارنة ==، أو على الأقل يجب عليهم) ويمكنك غورانتي كيف تم تخصيصها وتناسبها في النطاقات المذكورة أعلاه ثم == آمن.

قد يؤدي بعض VMS إلى زيادة هذا الحجم، لكنه أكثر أمانا يفترض أن أصغر حجم كما هو محدد من قبل المواصفات Langauge بدلا من الاعتماد على سلوك VM معين، إلا إذا كنت حقا بحاجة حقا إلى.

تطبيقات المساواة (كائن O) طريقة تبدأ دائما مع

if(this == o) return true;

لذلك استخدام equals حتى و إن == صحيح حقا ليس الكثير من ضرب الأداء.

أوصي دائما * باستخدام equals طريقة على الكائنات.

* بالطبع هناك عدة مرات يجب أن لا تأخذ هذه النصيحة.

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

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

تجدر الإشارة إلى أن القيم المركبة التلقائية ستستخدم كائن مجمع إذا كانت متوفرة. هذا هو السبب (عدد صحيح) 0 == (عدد صحيح) 0 ولكن (عدد صحيح) 128! = (عدد صحيح) 128 ل Java 6U13

أحب أن أرى النتيجة بصريا:

  public static void main(String[] args)
  {
        Integer a = 126; //no boxed up conversion, new object ref
        Integer b = 126; //no boxed up conversion, re-use memory address
        System.out.println("Are they equal? " + (a == b)); // true
        Integer a1 = 140; //boxed up conversion, new object
        Integer b1 = 140; //boxed up conversion, new object
        System.out.println("Are they equal? " + (a1 == b1)); // false
        System.out.println("Are they equal? " + (new Long(5) == new Long(5))); // false
  }

== يقارن مرجع الكائن أثناء equals(Object obj) يقارن لكائن المساواة. إذا كان هناك من أي وقت مضى أكثر من مثيل واحد من كائن يساوي موجود ثم أنت يجب استعمال equals للمقارنة المساواة.

أمثلة:

Integer i1 = new Integer(12345);
Integer i2 = new Integer(12345);

هذه هي مثيلات كائن مختلفة ولكن متساوية وفقا لمساواة عدد صحيح، لذلك يجب عليك استخدامها equals(Object obj)

public enum Gender {
    MALE, FEMALE;
}

في هذه الحالة، سيكون هناك حالة واحدة فقط من FEMALE في الوجود لذلك == هو آمن للاستخدام.

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