كيفية تهيئة خريطة ثابتة في Java: برنامج تعليمي خطوة بخطوة لمن سئم من كتابة الكود المتكرر
\n\nمرحبًا يا زميل! إذا كنت قد كتبت بلغة Java من قبل، فمن المؤكد أنك واجهت موقفًا تحتاج فيه إلى تعريف خريطة Map ثابتة ثابتة — على سبيل المثال، لتخزين رموز الأخطاء، أو تطابقات "مفتاح-قيمة"، أو ببساطة بيانات مرجعية. قد يبدو الأمر بسيطًا، أليس كذلك؟ لكن في كل مرة أرى فيها كتلًا ضخمة من static { ... } مع الكثير من put() في الكود، أود أن أسأل: "أليس هناك طريقة أكثر أناقة؟"
المفاجأة: هناك، وليس واحدة فقط. في هذه المقالة، سنستعرض جميع الطرق الشائعة لتهيئة خريطة Map ثابتة في Java — من "الحلول المؤقتة" القديمة إلى الصياغة الحديثة في Java 9+ وأدوات Guava. هيا بنا!
لماذا الخريطة الثابتة هي مشكلة؟
\n\nالمتغير الثابت في Java يتم تهيئته مرة واحدة عند تحميل الفئة. إذا كان من نوع Map، فيجب ملؤه بالبيانات قبل أن يتمكن أي شخص من الوصول إليه. المشكلة هي أن Map هي واجهة وليست فئة محددة، لذا لا يمكنك ببساطة كتابة public static Map وتمرير القيم مباشرة. تحتاج إلى إنشاء مثيل (مثل HashMap) ثم ملؤه. وهنا تبدأ المتعة.
دعنا نلقي نظرة على النهج الكلاسيكي الذي لا يزال موجودًا في المشاريع القديمة.
\n\nالطريقة 1: الكتلة الثابتة الكلاسيكية (ما يعادل "طريقة الأجداد")
\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Config {\n public static final Map<Integer, String> HTTP_STATUS_CODES;\n\n static {\n HTTP_STATUS_CODES = new HashMap<>();\n HTTP_STATUS_CODES.put(200, "OK");\n HTTP_STATUS_CODES.put(404, "Not Found");\n HTTP_STATUS_CODES.put(500, "Internal Server Error");\n HTTP_STATUS_CODES.put(302, "Found");\n }\n}\n\nالإيجابيات: واضحة، تعمل في كل مكان (Java 1.0+)، سهلة القراءة للمبتدئين.
\nالسلبيات: مطولة، تحتاج إلى تعريف كتلة منفصلة، من السهل نسيان static. إذا كان لديك 10 خرائط من هذا القبيل، يتحول الكود إلى ورقة ضخمة.
الطريقة 2: التهيئة بالأقواس المزدوجة (DBI) — "سحر الأقواس المتعرجة"
\n\nذات مرة، لاحظ مطور ذكي أنه يمكن استخدام فئة مجهولة وكتلة تهيئة المثيل. يبدو الأمر كالتالي:
\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Config {\n public static final Map<Integer, String> HTTP_STATUS_CODES = new HashMap<>() {{\n put(200, "OK");\n put(404, "Not Found");\n put(500, "Internal Server Error");\n put(302, "Found");\n }};\n}\n\nالقوس المتعرج الأول هو إنشاء فئة مجهولة من HashMap، والثاني هو كتلة تهيئة المثيل (مثل المُنشئ ولكن بدون اسم). يبدو مضغوطًا وحتى جميلًا. لكن...
السلبيات:
\n- \n
- في كل مرة يتم إنشاء فئة مجهولة، مما يزيد من حجم ملف class والتحميل على ClassLoader. \n
- إذا تم تعريف الخريطة كـ
static final، فسيتم إنشاء الفئة المجهولة على أي حال — وهذا غير فعال. \n - تحتفظ DBI بمرجع للفئة الخارجية (إذا تم استخدامها داخل سياق غير ثابت)، مما قد يؤدي إلى تسرب الذاكرة. \n
- لم تعد تعمل مع
Map.of(Java 9+) — ولكن المزيد عن ذلك لاحقًا. \n
أود أن أقول إن DBI هي "خدعة لطيفة للمقابلات"، ولكن في الإنتاج من الأفضل تجنبها. هناك الكثير من المخاطر الخفية.
\n\nالطريقة 3: Stream API و Collectors.toMap (Java 8+)
\n\nجلبت Java 8 Stream API، وتعلمنا على الفور تهيئة الخريطة من خلال التدفقات. الفكرة بسيطة: إنشاء تدفق من الأزواج، ثم تجميعها في خريطة.
\n\nimport java.util.Map;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\npublic class Config {\n public static