أي عيب لاستخدام كائنات تعسفية كمفاتيح خريطة في جافا؟

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

  •  10-07-2019
  •  | 
  •  

سؤال

لدي نوعان من الكائنات في طلبي حيث كل كائن من نوع واحد لديه كائن واحد مقابل من النوع الآخر.

الخيار الواضح لتتبع هذه العلاقة هو Map<type1, type2>, ، مثل hashmap. لكن بطريقة ما ، أنا مشبوه. هل يمكنني استخدام كائن كمفتاح في الخريطة ، وتمريره ، وجعله يجلس في مجموعة أخرى أيضًا ، واسترداد شريكه من الخريطة في أي وقت؟

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

أي تحذيرات أخرى؟ هل يجب أن أستخدم شيئًا آخر لربط أزواج الكائن ، مثل الرقم الذي أنشأه نفسي؟

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

المحلول

  1. يحتاج المفتاح إلى التنفيذ .equals() و .hashCode() بشكل صحيح
  2. المفتاح لا يجب يتم تغييرها بأي طريقة تتغير .hashCode() القيمة أثناء استخدامها كمفتاح
  3. من الناحية المثالية ، أي كائن يستخدم كمفتاح في أ HashMap يجب أن يكون غير قابل للتغيير. هذا من شأنه أن يضمن تلقائيًا أن 2. يتم اعتباره دائمًا صحيحًا.
  4. قد يتم الاحتفاظ بالكائنات التي يمكن أن تكون خلاف ذلك عند استخدامها كمفتاح و/أو قيمة.

نصائح أخرى

لدي نوعان من الكائنات في طلبي حيث كل كائن من نوع واحد لديه كائن واحد مقابل من النوع الآخر.

هذا يبدو حقًا وكأنه علاقة HAS-A وبالتالي يمكن تنفيذها باستخدام سمة بسيطة.

يعتمد ذلك على تنفيذ الخريطة التي تختارها:

  • خريطة التجزئة الاستخدامات يساوي () و hashcode (). بشكل افتراضي (في الكائن) ، تعتمد هذه على هوية الكائن ، والتي ستعمل بشكل جيد ما لم تقم بتسلسل/هجر. من خلال التنفيذ المناسب لـ Equals () و HashCode () استنادًا إلى محتوى الكائن ، لن تواجه أي مشاكل ، طالما أنك لا تعدله بينما يكون مفتاحًا في خريطة التجزئة.

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

يمكنك استخدام خريطة قياسية ، ولكن القيام بذلك سوف تحافظ على إشارات قوية إلى كائناتك في الخريطة. إذا تمت الرجوع إلى كائناتك في بنية أخرى وتحتاج إلى الخريطة فقط لربطها معًا ، فكر في استخدام AdentialHashMap.

وبالمناسبة ، لا يتعين عليك تجاوز المساواة والرمز الحزبي إلا إذا كان عليك التفكير في عدة حالات كائن ما متساوٍ ...

هل يمكنني استخدام كائن كمفتاح في الخريطة ، وتمريره ، وجعله يجلس في مجموعة أخرى أيضًا ، واسترداد شريكه من الخريطة في أي وقت؟

نعم ، لا مشكلة هنا على الإطلاق.

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

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

أي تحذيرات أخرى؟ هل يجب أن أستخدم شيئًا آخر لربط أزواج الكائن ، مثل الرقم الذي أنشأه نفسي؟

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

يمكن أن يكون أي كائن مفتاح خريطة. الشيء المهم هنا هو التأكد من تجاوزك .equals () و .hashcode () لأي كائنات سيتم استخدامها كمفاتيح الخرائط.

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

يمكنك تجاوز رمز hashcode لأنه يجب أن يكون متسقًا مع متساوٍ. هذا بحيث تكون الكائنات التي حددتها على أنها تساوي التجزئة.

نقاط الفشل هي وظائف Hashcode و Equals. إذا لم ينتجوا قيم الإرجاع المتسقة والسليمة ، فسوف تتصرف الخريطة بشكل غريب. جافا فعالة لديه قسم كامل عليهم وهو موصى به للغاية.

قد تفكر في مجموعة Google bimap.

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