Map<Integer, String> map = new HashMap<>();
map.put(1, "string 1");
map.put(2, "string 2");
map.put(3, "string 3");
وهذه هي كيفية الحصول على القيم حسب المفتاح:
String string1 = map.get(1);
String string2 = map.get(2);
String string3 = map.get(3);
إذا كان كل ما سبق واضحا، فلننتقل إلى إجاباتنا على الأسئلة الشائعة!
0. كيفية التكرار عبر جميع قيم الخريطة
يعد التكرار على القيم هو العملية الأكثر شيوعًا التي تقوم بها باستخدام الخرائط. يتم تخزين جميع أزواج القيمة الرئيسية في واجهة Map.Entry الداخلية، وللحصول عليها تحتاج إلى الاتصال بـentrySet()
. تقوم بإرجاع مجموعة من الأزواج التي يمكن تكرارها من خلال:
for(Map.Entry<Integer, String> entry: map.entrySet()) {
// get key
Integer key = entry.getKey();
// get value
String value = entry.getValue();
}
Или используя итератор:
Iterator<Map.Entry<Integer, String>> itr = map.entrySet().iterator();
while(itr.hasNext()) {
Map.Entry<Integer, String> entry = itr.next();
// get key
Integer key = entry.getKey();
// get value
String value = entry.getValue();
}
1. كيفية تحويل الخريطة إلى القائمة
تحتوي واجهة الخريطة على ثلاث طرق تقوم بإرجاع قائمة العناصر:- keySet() - يُرجع مجموعة من المفاتيح؛
- القيم () - ترجع مجموعة من القيم؛
- الإدخال () - يُرجع مجموعة من مجموعات القيمة الرئيسية.
ArrayList
، ستلاحظ أن هناك منشئًا به وسيطة من النوع Collection. نظرًا لأن Set هو سليل Collection، فيمكن تمرير نتائج جميع الطرق المذكورة أعلاه إلى مُنشئ الفئة ArrayList
. لذلك سنقوم بإنشاء قوائم جديدة وملئها بالقيم من Map
:
// key list
List<Integer> keyList = new ArrayList<>(map.keySet());
// value list
List<String> valueList = new ArrayList<>(map.values());
// key-value list
List<Map.Entry<Integer, String>> entryList = new ArrayList<>(map.entrySet());
2. كيفية فرز مفاتيح الخريطة
يعد فرز الخرائط أيضًا عملية شائعة إلى حد ما في البرمجة. بل إنني مهتم في القراءة أكثر:-
ضع Map.Entry في قائمة وقم بفرزها باستخدام Comparator .
في المقارنة سنقارن فقط مفاتيح الأزواج:
List
> list = new ArrayList(map.entrySet()); Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() { @Override public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) { return o1.getKey() - o2.getKey(); } }); إذا كنت تفهم lambdas، فيمكن اختصار هذا الإدخال بشكل كبير:
Collections.sort(list, Comparator.comparingInt(Map.Entry::getKey));
-
استخدم
SortedMap
، أو بتعبير أدق، تطبيقهTreeMap
، الذي يأخذ المقارنة في منشئه. سيتم تطبيق هذه المقارنة على مفاتيح الخريطة، لذا يجب أن تكون المفاتيح عبارة عن فئات تنفذ الواجهةComparable
:SortedMap<Integer, String> sortedMap = new TreeMap<>(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1 - o2; } });
وبالطبع، يمكن إعادة كتابة كل شيء باستخدام لامدا:
SortedMap<Integer, String> sortedMap = new TreeMap<>(Comparator.comparingInt(o -> o));
على عكس الطريقة الأولى، باستخدام SortedMap، سنقوم دائمًا بتخزين البيانات في شكل مرتبة.
3. كيفية فرز قيم الخريطة
هنا يجب عليك استخدام نهج مشابه للأسلوب الأول للمفاتيح - احصل على قائمة بالقيم وقم بفرزها في القائمة:List <Map.Entry<Integer, String>> valuesList = new ArrayList(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() {
@Override
public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
return o1.getValue().compareTo(o2.getValue());
}
});
ويبدو لامدا لهذا كما يلي:
Collections.sort(list, Comparator.comparing(Map.Entry::getValue));
4. ما الفرق بين HashMap وTreeMap وHashtable
كما ذكرنا سابقًا، هناك 3 تطبيقات رئيسية لواجهة الخريطة. كل واحد منهم له خصائصه الخاصة:-
ترتيب العناصر.
HashMap
ولاHashtable
تضمن أنه سيتم تخزين العناصر بالترتيب الذي تمت إضافتها به. بالإضافة إلى ذلك، فهي لا تضمن عدم تغير ترتيب العناصر بمرور الوقت. وهو بدورهTreeMap
يضمن تخزين العناصر بالترتيب الذي تمت إضافتها به أو وفقًا لمقارن معين. -
قيم صالحة.
HashMap
يسمح لك بالحصول على مفتاح وقيمة فارغة،HashTable
لا. لا يمكن لـ TreeMap استخدام القيم الخالية إلا إذا سمح المقارن بذلك. بدون استخدام المقارنة (عن طريق تخزين الأزواج بترتيب إضافتها)، لا يُسمح بالقيم الخالية. -
التزامن. متزامنة فقط
HashTable
، والباقي ليس كذلك. إذا لم يتم الوصول إلى الخريطة من خلال سلاسل رسائل مختلفة، فمن المستحسن استخدام HashMap بدلاً من HashTable.
خريطة التجزئة | HashTable | خريطة الشجرة | |
---|---|---|---|
ترتيب العناصر | لا | لا | نعم |
فارغة كقيمة | نعم | لا | ليس حقيقيًا |
سلامة الخيط | لا | نعم | لا |
التعقيد الخوارزمي للبحث عن العناصر | يا(1) | يا(1) | يا(سجل ن) |
بنية البيانات تحت غطاء محرك السيارة | جدول التجزئة | جدول التجزئة | شجرة حمراء سوداء |
5. كيفية إنشاء خريطة ثنائية الاتجاه
في بعض الأحيان يصبح من الضروري استخدام بنية بيانات تكون فيها المفاتيح والقيم فريدة من نوعها، أي أن الخريطة ستحتوي على أزواج المفاتيح والمفاتيح. تتيح لك بنية البيانات هذه إنشاء "عرض/بحث مقلوب" على الخريطة. أي أنه يمكننا العثور على مفتاح حسب قيمته، وتسمى بنية البيانات هذه بالخريطة ثنائية الاتجاه، وهي للأسف غير مدعومة من قبل JDK. ولكن، لحسن الحظ، يمكن العثور على تطبيقه في Apache Common Collections أو مكتبات Guava. هناك يطلق عليه BidiMap وBiMap، على التوالي. تفرض هذه التطبيقات قيودًا على تفرد المفاتيح والقيم. وهذا يخلق علاقة واحد لواحد.6. كيفية إنشاء خريطة فارغة
هناك طريقتان لإنشاء خريطة فارغة:-
تهيئة الكائن العادي:
Map<Integer, String> emptyMap = new HashMap<>();
-
إنشاء خريطة فارغة غير قابلة للتغيير:
Map<Integer, String> emptyMap = Collections.emptyMap();
UnsupportedOperationException
استثناء. في هذه المقالة، نظرنا إلى الأسئلة الأكثر شيوعًا التي قد تكون لديك عند استخدام واجهة الخريطة.
GO TO FULL VERSION