JavaRush /مدونة جافا /Random-AR /HashMap في Java - ما هو نوع الخريطة؟

HashMap في Java - ما هو نوع الخريطة؟

نشرت في المجموعة
مرحبًا! اليوم سنتحدث عن بنية بيانات أخرى - الخريطة. اسمها الرسمي الروسي هو "المصفوفة النقابية"، لكنه لا يستخدم كثيرًا. الخيارات الأكثر شيوعًا هي "القاموس" أو "الخريطة" أو (في أغلب الأحيان) "خريطة" العامية :) داخل الخريطة، يتم تخزين البيانات بتنسيق "المفتاح" - "القيمة"، أي في أزواج. يمكن أن تكون كل من المفاتيح والقيم أي كائنات — أرقام أو سلاسل أو كائنات من فئات أخرى.

كيف تختلف الخريطة عن هياكل البيانات الأخرى

في السابق، نظرنا إلى هياكل البيانات حيث يتم تخزين العناصر بنفسها. في المصفوفة، أو ArrayList / LinkedList ، نقوم بتخزين عدد معين من العناصر. ولكن ماذا لو تغيرت مهمتنا قليلاً؟ على سبيل المثال، تخيل أننا نواجه مهمة إنشاء قائمة تضم 100 شخص، حيث سيتم تخزين الاسم الكامل للشخص ورقم جواز السفر. من حيث المبدأ، الأمر ليس بهذه الصعوبة. على سبيل المثال، يمكنك احتواء كليهما في سطر وإنشاء قائمة من السطور مثل هذا: "Anna Ivanovna Reshetnikova, 4211 717171." لكن هذا الحل له عيبان. أولاً، قد نحتاج إلى وظيفة البحث عن جواز السفر. ومع هذا التنسيق لتخزين المعلومات سيكون مشكلة. وثانيًا، لن يمنعنا شيء من إنشاء شخصين مختلفين لهما نفس أرقام جواز السفر. وهذا هو أخطر عيب في حلنا. يجب استبعاد مثل هذه الحالات تماما، فلا يوجد شخصان لهما نفس رقم جواز السفر. هنا تأتي الخريطة وميزاتها المعلنة لمساعدتنا (تخزين البيانات في زوج بتنسيق "المفتاح" - "القيمة"). دعونا نلقي نظرة على تطبيق الخريطة الأكثر شيوعًا - فئة Java HashMap .HashMap - أي نوع من الخريطة هذا؟  - 1

إنشاء HashMap في Java والعمل مع الفصل

هذا التنفيذ بسيط جدًا في الإنشاء:
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

}
قمنا هنا بإنشاء قاموس سيتم فيه تخزين العناصر بتنسيق "سلسلة الأرقام". سيكون الرقم هو المفتاح، وستكون السلسلة هي القيمة. كما أشرنا أيضًا إلى نوع المفاتيح التي سنحصل عليها ( Integer) ونوع القيم ( String). لماذا هو كذلك؟ أولاً، يكون المفتاح الموجود في HashMap فريدًا دائمًا . سيكون هذا مفيدًا لنا لأنه يمكننا استخدام رقم جواز السفر كمفتاح وتجنب التكرارات. وسيكون السطر الذي يحتوي على الاسم الكامل بمثابة قيمة (يمكن بسهولة تكرار الاسم الكامل لأشخاص مختلفين، ولا حرج في ذلك بالنسبة لنا).

إضافة زوج جديد إلى HashMap

تبدو هذه المهمة كما يلي:
public class Main {

   public static void main(String[] args) {
       HashMap<Integer, String> passportsAndNames = new HashMap<>();


       passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
       passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
       passportsAndNames.put(8082771, "Donald John Trump");
       System.out.println(passportsAndNames);

   }

}
يتم استخدام الطريقة لهذا put(). بالإضافة إلى ذلك، لدى HashMap طريقة متجاوزة toString()بحيث يمكن طباعتها على وحدة التحكم. سيبدو الناتج كما يلي: {212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump, 162348=Ivan Mikhailovich Serebryakov}

ميزات مفاتيح HashMap

الآن دعونا نتحقق مما إذا كانت المفاتيح فريدة حقًا؟ دعنا نحاول إضافة عنصر جديد بمفتاح موجود بالفعل في الخريطة:
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");
   passportsAndNames.put(162348, "Viktor Mikhailovich Stychkin");//repeat key

   System.out.println(passportsAndNames);

}
الإخراج: {212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump, 162348=Viktor Mikhailovich Stychkin} تمت الكتابة فوق العنصر السابق بالمفتاح 162348، كما ترون. "المفتاح" كان يسمى المفتاح لسبب ما. يتم الوصول إلى القيم الموجودة في HashMap عن طريق المفتاح (ولكن ليس العكس - لا يمكن الحصول على المفتاح بالقيمة، لأنه يمكن تكرار القيم). يظهر هذا بوضوح في أمثلة الحصول على عنصر، وكذلك إزالة عنصر من HashMap:
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");

   String lidiaName = passportsAndNames.get(212133);
   System.out.println(lidiaName);


   passportsAndNames.remove(162348);
   System.out.println(passportsAndNames);

}
من أجل الحصول على قيمة أو حذف زوج من القاموس، يجب علينا تمرير المفتاح الفريد المطابق لهذه القيمة بالضبط إلى get()الطرق . لا توجد فهارس رقمية، كما هو الحال في المصفوفات أو القوائم، في HashMap - يتم الوصول إلى القيمة عن طريق المفتاح. إخراج وحدة التحكم: Lidiya Arkadyevna Bublikova {212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump}remove()

التحقق من وجود المفتاح والقيمة

في فئتي ArrayList و LinkedList ، يمكننا التحقق مما إذا كانت القائمة تحتوي على عنصر معين. يتيح لك HashMap أيضًا القيام بذلك، ولكلا الجزأين من الزوج: فهو يحتوي على طرق containsKey()(التحقق من وجود مفتاح) و containsValue()(التحقق من وجود قيمة).
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");


   System.out.println(passportsAndNames.containsKey(11111));
   System.out.println(passportsAndNames.containsValue("Donald John Trump"));

}
الإخراج: خطأ صحيح

الحصول على قائمة بجميع المفاتيح والقيم

ميزة أخرى ملائمة لـ HashMap هي أنه يمكنك الحصول بشكل منفصل على قائمة بجميع المفاتيح وجميع القيم . keySet()وتستخدم لهذا الأساليب values():
public class Main {

   public static void main(String[] args) {

       HashMap<Integer, String> passportsAndNames = new HashMap<>();

       passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
       passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
       passportsAndNames.put(8082771, "Donald John Trump");

       Set<Integer> keys = passportsAndNames.keySet();
       System.out.println("Keys: " + keys);

       ArrayList<String> values = new ArrayList<>(passportsAndNames.values());
       System.out.println("Values: " + values);

   }

}
يتم استخراج المفاتيح في المجموعة Set. خصوصيتها هي أنها لا يمكن أن تحتوي على عناصر متكررة. الشيء الرئيسي الذي يجب تذكره الآن هو أنه يمكن إخراج قائمة جميع المفاتيح من HashMap إلى مجموعة منفصلة. في المثال قمنا بحفظ القيم إلى وضعها الطبيعي ArrayList. مخرجات وحدة التحكم: المفاتيح: [212133، 8082771، 162348] القيم: [Lidiya Arkadyevna Bublikova، Donald John Trump، Ivan Mikhailovich Serebryakov]size() تعمل الأساليب clear()تمامًا كما في الهياكل السابقة التي مررنا بها: تُرجع الطريقة الأولى عددًا من العناصر في القاموس في الوقت الحالي، والثاني يحذف جميع العناصر.
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");

   System.out.println(passportsAndNames.size());
   passportsAndNames.clear();
   System.out.println(passportsAndNames);

}
الإخراج: 3 {} للتحقق مما إذا كانت HashMap لدينا تحتوي على عنصر واحد على الأقل، يمكننا استخدام الطريقة isEmpty():
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");

   if (!passportsAndNames.isEmpty()) {

       System.out.println(passportsAndNames);

   }

}
الإخراج: {212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump, 162348=Ivan Mikhailovich Serebryakov} الآن لن نقوم بالإخراج إلى وحدة التحكم إلا بعد التحقق الأولي :)

الجمع بين خريطتين في واحدة

نقطة أخرى مثيرة للاهتمام هي أنه يمكن دمج خريطتين في خريطة واحدة . هناك طريقة لهذا putAll(). نسميها على HashMap الأول ، ونمرر الثاني كوسيطة، وستتم إضافة عناصر الثاني إلى الأول:
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();
   HashMap<Integer, String> passportsAndNames2 = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");

   passportsAndNames2.put(917352, "Alexey Andreevich Ermakov");
   passportsAndNames2.put(925648, "Maxim Olegovich Arkharov");


   passportsAndNames.putAll(passportsAndNames2);
   System.out.println(passportsAndNames);

}
الإخراج: {917352=أليكسي أندريفيتش إرماكوف، 212133=ليديا أركاديفنا بوبليكوفا، 8082771=دونالد جون ترامب، 925648=مكسيم أوليغوفيتش أرخاروف، 162348=إيفان ميخائيلوفيتش سيريبرياكوف} تم نسخ جميع عناصر جوازات السفر والأسماء 2 إلى جوازات السفر والأسماء . الآن دعونا نلقي نظرة على مثال أكثر تعقيدا. وهي التكرار عبر HashMap في حلقة.
for (Map.Entry entry: passportsAndNames.entrySet()) {

   System.out.println(entry);

}
الواجهة Map.Entryتعني فقط زوجًا من القيمة الرئيسية داخل القاموس. تقوم الطريقة entrySet()بإرجاع قائمة بجميع الأزواج في HashMap الخاصة بنا (نظرًا لأن خريطتنا تتكون من أزواج الإدخال هذه فقط، فإننا نكررها على أزواج، وليس مفاتيح أو قيم منفصلة). الخلاصة: 212133=Lidiya Arkadyevna Bublikova 8082771=Donald John Trump 162348=Ivan Mikhailovich Serebryakov احفظ هذا المقال للمستقبل: https://habr.com/ru/post/128017/ الآن من السابق لأوانه قراءته، ولكن في المستقبل ، عندما تتعرف على استخدام HashMap، سيساعدك ذلك على فهم كيفية عمل بنية البيانات هذه من الداخل. لا تنس أيضًا الاطلاع على وثائق Oracle الرسمية على HashMap.
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION