Lombok: مشكلة مع hashCode () على سمة فارغة عند استخدامها في بنية قائمة على التجزئة

تم إنشاؤها على ١٩ يوليو ٢٠١٩  ·  3تعليقات  ·  مصدر: projectlombok/lombok

يمكن أن يتسبب التعليق التوضيحي @EqualsAndHashCode الذي يستخدم سمة طويلة مثل pk في حدوث سلوك غير محدد عند استخدامه مع بنية قائمة على التجزئة (مثل HashSet).

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

<strong i="9">@Entity</strong>
@EqualsAndHashCode(of = "pk")
class Foo {

    <strong i="10">@Id</strong>
    private Long pk;

    private LocalDate createdAt;

}
<strong i="13">@Entity</strong>
class Foo {

    <strong i="14">@Id</strong>
    private Long pk;

    private LocalDate createdAt;

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        Object $pk = this.getPk();
        int result = result * 59 + ($pk == null ? 43 : $pk.hashCode());
        return result;
    }

    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
}

لذلك عندما يكون المثيل مع pk = null والآخر مع pk = 43 ، فإنه سيعيد نفس كود التجزئة ويمكن اعتباره كما هو في البنية القائمة على التجزئة ، أيهما ليسوا كذلك.

وفي حالة استخدام OmniFaces ListConverter الذي يستخدم toString لدينا نفس المشكلة.

ربما يُرجع رمز التجزئة لمثيل الكائن بدلاً من الثابت الثابت

هل اتخذت هذا السيناريو بالفعل ، أو هل تعرف طريقة ما لحل هذا الموقف ؟!

معلومات الإصدار

  • لومبوك => 1.18.8
  • النظام الأساسي => Windows 10 JDK 11.0.4 IntelliJ

التعليق الأكثر فائدة

ربما يكون الرقم 43 جيدًا مثل أي رقم آخر ، وأفضل من -1 و 0 و 1. يجعله قابلاً للتكوين يضيف عبء صيانة لقيمة مضافة منخفضة جدًا.

سيؤدي استخدام كود تجزئة الهوية إلى كسر عقد التساوي.

ال 3 كومينتر

لذلك عندما يكون المثيل مع pk = null والآخر مع pk = 43 ، فإنه سيعيد نفس كود التجزئة

هذا لا يهم. علاوة على ذلك ، ستكون هناك دائمًا تصادمات تجزئة ، بغض النظر عن اختيارك.

لاحظ أن Arrays.hashCode و String.hashCode والعديد من الآخرين يتسببون في أطنان من الاصطدامات ، بدون داع.

ربما يُرجع رمز التجزئة لمثيل الكائن بدلاً من الثابت الثابت

في الكود المكتوب يدويًا ، أؤكد أنه لم يتم استدعاؤه قبل تعيين id . هذا أمر غريب بالتأكيد ، لكن كل البدائل كذلك.

سيكون من الممكن إنشاء معلمة تعليق توضيحي يمكنها تحديد القيمة التي يجب استخدامها عندما يكون PK فارغًا ، في هذه الحالة. للافتراضي 43.

هذا من شأنه أن يعطي المزيد من التحكم للمطور.

@EqualsAndHashCode(of = "pk", ifAnyNull = -1)

لذلك سيستخدم -1 بدلاً من 43 ، لأي حقل كان فارغًا

ربما يكون الرقم 43 جيدًا مثل أي رقم آخر ، وأفضل من -1 و 0 و 1. يجعله قابلاً للتكوين يضيف عبء صيانة لقيمة مضافة منخفضة جدًا.

سيؤدي استخدام كود تجزئة الهوية إلى كسر عقد التساوي.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات