تعد واجهة Java Map جزءًا من إطار عمل Java Collection، ولكنها ليست نوعًا فرعيًا من واجهة المجموعة. لذا فهو يتصرف بطريقة مختلفة مقارنة بالقوائم أو كائنات المجموعة الأخرى على سبيل المثال. يمثل كل عنصر من عناصر Map<Key, Value> زوجًا من القيمة الرئيسية. يعد كل من المفتاح والقيمة بعض الكائنات. جميع المفاتيح في خريطة معينة فريدة من نوعها، في حين أن القيم ليست كذلك، لذلك يمكن تكرارها. قد تفكر في Map in Java كنوع من القاموس أو كتالوج المتجر عبر الإنترنت، حيث يمكنك العثور على أي عنصر باستخدام فهرسه الفريد. المفتاح هو معرف فريد للقيمة في الخريطة. على سبيل المثال، في Map<String, Item> String هو معرف لبعض العناصر من المتجر عبر الإنترنت. وفقًا للوثائق، تحتوي الخريطة على الواجهات الفرعية التالية:
الارتباطات _
خريطة متزامنة<K,V> ;
ConcurrentNavigableMap<K,V> ;
LogicalMessageContext ;
سياق الرسالة ؛
NavigableMap<K,V> ;
SOAPMessageContext ;
SortedMap<K,V> .
وينفذ الطبقات:
AbstractMap
صفات
AuthProvider
ConcurrentHashMap
ConcurrentSkipListMap
EnumMap
خريطة التجزئة
جدول التجزئة
IdentityHashMap
LinkedHashMap
أسباب حالة الطابعة
ملكيات
مزود
تلميحات التقديم
SimpleBindings
TabularDataSupport
خريطة الشجرة
UIDefaults
WeakHashMap
Java AbstractMap هي فئة مجردة تنفذ معظم واجهة الخريطة.
Java HashMap عبارة عن بنية بيانات لتخزين أزواج القيمة الرئيسية باستخدام جدول التجزئة.
Java TreeMap عبارة عن بنية بيانات لاستخدام الشجرة، أي عرضها باستخدام مفاتيح مرتبة.
يستخدم WeakHashMap جدول تجزئة بمفاتيح ضعيفة، ويعرض القيم التي يمكن لجامع البيانات المهملة حذفها إذا لم تعد مستخدمة.
LinkedHashMap عبارة عن خريطة بترتيب إضافة العناصر، وتسمح بالتكرار بترتيب الإدراج.
يقوم EnumMap بتوسيع فئة AbstractMap للاستخدام مع مفاتيح التعداد.
يستخدم IdentityHashMap التحقق من التكافؤ المرجعي عند مقارنة المستندات، والتعيين باستخدام المفاتيح مقارنة باستخدام عملية
== بدلاً من طريقة
يساوي ()
نحن هنا مهتمون بتطبيقات Map Interface الأكثر شيوعًا: HashMap وTreeMap وLinkedHashMap. بالمناسبة، يعتمد ترتيب عناصر الخريطة على تطبيقات محددة. لنفترض أن TreeMap وLinkedHashMap لهما ترتيب يمكن التنبؤ به للعناصر، في حين لا يحتوي HashMap على ذلك.
طرق الخريطة
العمليات الرئيسية لأي خريطة هي إدراج العناصر وإزالتها والبحث عنها.
يقوم وضع الكائن العام (مفتاح الكائن، قيمة الكائن) بإدراج عنصر في الخريطة.
يقوم public void putAll(Map Map) بإدراج الخريطة المحددة داخل الخريطة.
إزالة الكائن العام (مفتاح الكائن) يحذف الإدخال وفقًا للمفتاح المحدد.
يقوم الحصول على الكائن العام (مفتاح الكائن) بإرجاع قيمة المفتاح المحدد.
منطقية عامة تحتوي على مفتاح (مفتاح الكائن) تبحث عن المفتاح المحدد من هذه الخريطة
يقوم Set keySet () العام بإرجاع طريقة عرض Set التي تحتوي على جميع المفاتيح
تقوم مجموعة الإدخال العامة () بإرجاع طريقة عرض المجموعة مع كافة المفاتيح والقيم.
ما هو هاشماب
ما هو هاشماب؟ هذا هو التطبيق الأكثر شيوعًا لواجهة Map<Key,Value>. تعتمد بنية البيانات هذه على مبدأ التجزئة.
المبدأ الرئيسي لعمل HashMap: التجزئة
لفهم ما هي خريطة التجزئة وكيف تعمل، دعونا نتحدث عن التجزئة ووظائف التجزئة أولاً. دالة التجزئة هي مجرد دالة بالمعنى الرياضي. لذلك هناك بعض قيمة الإدخال (كائن، جزء من البيانات) وتقوم الوظيفة بتحويلها باستخدام قاعدة مناسبة إلى قيمة إخراج - تجزئة. غالبًا ما يكون التجزئة رقمًا سداسيًا عشريًا بطول مناسب. قد تكون قواعد تحويل العمليات مختلفة، ولكنها تخضع للمبادئ التالية:
يحتوي إدخال (كائن) معين على رمز تجزئة معين.
إذا كان هناك كائنان متساويان، فإن رموز التجزئة الخاصة بهما متساوية أيضًا. والعكس ليس صحيحا.
إذا كانت رموز التجزئة مختلفة، فإن الكائنات بالتأكيد ليست متساوية.
في بعض الأحيان يمكن أن تحتوي الكائنات المختلفة على نفس رمز التجزئة. إنه حدث غير مرجح للغاية، يسمى "الاصطدام" ومن المفترض أن تقلل دالة التجزئة عالية الجودة من احتمالية الاصطدامات.
في جافا، كل كائن لديه رمز التجزئة. يتم حسابه بواسطة طريقة hashCode لفئة الكائن، والفئة الأصلية لجميع كائنات Java. عادة، يتجاوز المطورون هذه الطريقة للفئات الخاصة بهم بالإضافة إلى الطرق المتساوية المرتبطة بها.
HashMap: كيف يعمل
لذلك صنف HashMap<K,V> حيث أن كل تطبيق Map يتكون من مفاتيح وقيم. يقوم بتخزين المفاتيح باستخدام مبادئ التجزئة. يتم تخزين أزواج قيمة مفتاح HashMap داخل "مجموعات"، وتقوم هذه المجموعات معًا ببناء "جدول"، ومصفوفة داخلية من القوائم المرتبطة وحجمها الأولي هو 16 . يستخدم HashMap في Java رمز التجزئة للمفتاح لتحديد مجموعة حيث يجب تعيين زوج المفتاح/القيمة: الميزة الصعبة في HashMap هي أن كل خلية (دلو) في الجدول [] لا تحتفظ بزوج واحد فقط بل عدة أزواج. ولا يتم تخزينها ككائن صريح (مثل LinkedList)، ولكن كسلسلة ضمنية. يتم إنشاء السلسلة نظرًا لأن كل زوج يخزن رابطًا للزوج التالي. أي أن جميع أزواج HashMap متناثرة عبر 16 سلسلة. عند وضع زوج جديد في الجدول، يتم أخذ تجزئة المفتاح بعين الاعتبار. هذا التجزئة ليس وظيفة رمز التجزئة المضمنة في الكائن الرئيسي. ويعتبر أن يكون في حدود 0-15. تتم إضافة الزوج إلى سلسلة الأزواج المخزنة في الدلو باستخدام مؤشر التجزئة. هذا النهج يعطينا تسريع البحث. أثناء البحث عن زوج حسب المفتاح، ليست هناك حاجة لتصفح الجدول بأكمله. يتم أخذ تجزئة المفتاح في الاعتبار ويتم فحص السلسلة المخزنة في الخلية مع فهرس التجزئة فقط. إذا كان هناك عدد كبير جدًا من الأزواج في HashMap، تصبح السلاسل طويلة جدًا. ثم يزداد حجم المصفوفة، ويتم إعادة حساب تجزئة كافة الكائنات المخزنة، ويتم توزيعها على طول سلاسل جديدة.
إعلان HashMap
إذا ذهبت إلى كود HashMap للفئة ستجد الإعلان التالي:
حيث K هو نوع المفاتيح التي تحتفظ بها هذه الخريطة و V - نوع القيم المعينة. هذا مثال على إعلان HashMap مع مفتاح عدد صحيح وقيمة سلسلة في التعليمات البرمجية الخاصة بك:
يقوم الحصول على الكائن (مفتاح الكائن) بإرجاع قيمة المفتاح المحدد؛
يقوم وضع الكائن (Key k، Value v) بإدراج تعيين قيمة المفتاح في الخريطة؛
إزالة الكائن (مفتاح الكائن) يزيل التعيين للمفتاح المحدد من هذه الخريطة إذا كان موجودًا؛
يزيل الفراغ الواضح () جميع أزواج القيمة الرئيسية من HashMap؛
يقوم Object clone() بإرجاع نسخة سطحية من مثيل HashMap دون استنساخ المفاتيح والقيم؛
تحتوي القيمة المنطقية على مفتاح (مفتاح الكائن) على إرجاع صحيح إذا تم العثور على المفتاح المحدد في الخريطة، وخطأ إذا لم يكن كذلك؛
boolean يحتوي على قيمة (قيمة الكائن) يُرجع صحيحًا إذا تم العثور على المفتاح المحدد في الخريطة، ويُرجع خطأ إذا لم يكن كذلك؛
boolean isEmpty() يُرجع صحيحًا إذا كانت الخريطة فارغة، وخطأ إذا لم تكن كذلك؛
يقوم Set keySet() بإرجاع مجموعة المفاتيح التي تم جلبها من الخريطة؛
int size() يُرجع كمية تعيين القيمة الرئيسية؛
تُرجع قيم المجموعة () مجموعة من قيم الخريطة؛
إزالة الكائن (مفتاح الكائن) يزيل زوج القيمة الرئيسية للمفتاح المحدد؛
void putAll(Map m) ينسخ جميع عناصر الخريطة إلى الخريطة الأخرى.
مثال جافا HashMap
لنقم بإنشاء برنامج باستخدام مثال Java HashMap لتوضيح كيفية عمله:
importjava.util.HashMap;importjava.util.Map;importjava.util.Iterator;importjava.util.Set;publicclassHashMap{publicstaticvoidmain(String[] args){{// HashMap declarationHashMap<Integer,String> myHashMap =newHashMap<Integer,String>();//Adding elements into HashMap
myHashMap.put(7,"Johnny");
myHashMap.put(8,"Ivy");
myHashMap.put(1,"Rick");
myHashMap.put(4,"Stan");
myHashMap.put(3,"Kyle");//print out the map content using IteratorSet set = myHashMap.entrySet();Iterator iterator = set.iterator();while(iterator.hasNext()){Map.Entry mapEntry =(Map.Entry) iterator.next();System.out.print("key: "+ mapEntry.getKey()+" value: ");System.out.println(mapEntry.getValue());}System.out.println("get an element from myHashMap via key and print the value out:");System.out.println(myHashMap.get(8));//print out hashMap on standard way:System.out.println(myHashMap);// Get values based on keyStringvar= myHashMap.get(2);//here we'll get null, we don't have such a keySystem.out.println("Value with key 2: "+var);var= myHashMap.get(7);System.out.println("Value with key 7: "+var);// Remove values based on key
myHashMap.remove(4);System.out.println("myHashMap after removing element:");System.out.println(myHashMap);
myHashMap.clear();System.out.println("myHashMap after total clearing:");System.out.println(myHashMap);}}}
نتيجة تشغيل البرنامج:
key: 1 value: Rick
key: 3 value: Kyle
key: 4 value: Stan
key: 7 value: Johnny
key: 8 value: Ivy
get an element from myHashMap via key and print the value out:
Ivy
{1=Rick, 3=Kyle, 4=Stan, 7=Johnny, 8=Ivy}
Value with key 2: null
Value with key 7: Johnny
myHashMap after removing element:
{1=Rick, 3=Kyle, 7=Johnny, 8=Ivy}
myHashMap after total clearing:
{}
خريطة الشجرة
تطبق TreeMap في Java أيضًا واجهة Map<Key,Value>، ولكنها تعتمد على بنية بيانات الشجرة ذات اللون الأحمر والأسود. تتكون الشجرة من "العقد" والخطوط التي تربط العقد - الفروع". العقدة "الجذر" موجودة في أعلى الشجرة. من الجذر، يمكن أن يكون هناك فروع وعقد. إنه هيكل هرمي، قد تفكر فيه هذه العقد هي "أبناء" للجذر. يمكن أن يكون للعقدة الفرعية أطفالها - العقد السفلية. العقد التي ليس لها أطفال تسمى "العقد النهائية" أو "الأوراق". الشجرة الثنائية هي شجرة، حيث تحتوي كل عقدة على صفر، واحد أو طفلين. شجرة البحث الثنائية عبارة عن هيكل، حيث تقوم كل عقدة داخلية بتخزين مفتاح، وأحيانًا قيمة مرتبطة، ولها شجرتين فرعيتين مميزتين ("يسار" و"يمين"). الشجرة عبارة عن شجرة بحث ثنائية قائمة على العقد تحافظ تلقائيًا على ارتفاعها (الحد الأقصى لعدد المستويات تحت الجذر) صغيرًا في مواجهة عمليات الإدراج والحذف التعسفية للعناصر.الشجرة ذات اللون الأحمر والأسود هي شجرة ثنائية متوازنة تتمتع بالخصائص التالية:
كل عقدة إما حمراء أو سوداء
الجذر دائما أسود
كل ورقة عبارة عن عقدة NIL (نوع فارغ، فارغ) وهي سوداء
إذا كانت العقدة حمراء، فإن أطفالها هم بالتأكيد أسود.
يحتوي كل مسار بسيط من عقدة إلى ورقة سليل على نفس العدد من العقد السوداء.
ميزات TreeMap
يستخدم TreeMap بنية بيانات شجرة لتخزين المفاتيح كعقد وفرز المفاتيح باستخدام خوارزمية Red-Black Tree. لذلك، يحافظ TreeMap على ترتيب إدخالاته وفقًا للترتيب الطبيعي لمفاتيحه. للأعداد الطبيعية ترتيب تصاعدي، للسلاسل - ترتيب أبجدي. يمكنك استخدام المقارنة إذا كنت بحاجة إلى تغيير منطق الطلب. يعد فرز الكائنات بطريقة طبيعية ميزة كبيرة لـ TreeMap، بالإضافة إلى العثور على بعض الكائنات باستخدام مرشحات وشروط مختلفة.
طرق TreeMap
يقوم الحصول على الكائن (مفتاح الكائن) بإرجاع قيمة المفتاح المقابل؛
يقوم وضع الكائن (مفتاح الكائن، قيمة الكائن) بإدراج تعيين في الخريطة؛
تقوم إزالة الكائن (مفتاح الكائن) بإزالة التعيين لهذا المفتاح إذا كان TreeMap يحتوي عليه؛
تحتوي القيمة المنطقية على مفتاح (مفتاح الكائن) على إرجاع صحيح إذا كانت هذه الخريطة تحتوي على تعيين للمفتاح المحدد؛
boolean يحتوي على قيمة (قيمة الكائن) يُرجع صحيحًا إذا قام TreeMap بتعيين مفتاح واحد أو أكثر للقيمة المحددة؛
يقوم Object firstKey() بإرجاع المفتاح الأول الموجود حاليًا في الخريطة التي تم فرزها؛
يقوم Object lastKey() بإرجاع المفتاح الأخير الموجود حاليًا في الخريطة التي تم فرزها؛
ينسخ void putAll(Map Map) جميع التعيينات من الخريطة المحددة إلى الخريطة؛
يقوم SetentrySet() بإرجاع عرض محدد للتعيينات
int size() يُرجع كمية تعيينات القيمة الرئيسية
تقوم قيم المجموعة () بإرجاع طريقة عرض مجموعة من القيم
يقوم Object clone() بإرجاع نسخة سطحية من TreeMap
يزيل void Clear() كافة التعيينات من TreeMap
SortedMap headMap(Object key_value) يُرجع عرضًا لجزء من الخريطة أقل من المعلمة key_value
يقوم Set keySet() بإرجاع طريقة عرض Set للمفاتيح الموجودة في المخطط الهيكلي
SortedMap subMap(K fromKey, K toKey) يُرجع عرضًا لجزء هذه الخريطة الذي تتراوح مفاتيحه من fromKey، شاملاً، إلى toKey، حصريًا
يقوم Object firstKey() بإرجاع المفتاح الأول من TreeMap.
مثال على TreeMap
importjava.util.TreeMap;importjava.util.Set;importjava.util.Iterator;importjava.util.Map;publicclassTreeMapExample{publicstaticvoidmain(String args[]){//TreeMap declarationTreeMap<Integer,String> myTreeMap =newTreeMap<Integer,String>();//put elements to TreeMap
myTreeMap.put(1,"Stuart");
myTreeMap.put(23,"Michael");
myTreeMap.put(7,"Johnny");
myTreeMap.put(5,"Ivy");
myTreeMap.put(2,"Alex");//Display and print out myTreeMap using IteratorSet set = myTreeMap.entrySet();Iterator iterator = set.iterator();while(iterator.hasNext()){Map.Entry myEntry =(Map.Entry) iterator.next();System.out.print("key: "+ myEntry.getKey()+" value: ");System.out.println(myEntry.getValue());}//TreeMap printed in classical waySystem.out.println(myTreeMap);//removing an element with the key =2
myTreeMap.remove(2);//myTreeMap after removing:System.out.println(myTreeMap);}}
نتيجة تشغيل البرنامج:
key: 1 value: Stuart
key: 2 value: Alex
key: 5 value: Ivy
key: 7 value: Johnny
key: 23 value: Michael
{1=Stuart, 2=Alex, 5=Ivy, 7=Johnny, 23=Michael}
{1=Stuart, 5=Ivy, 7=Johnny, 23=Michael}
LinkedHashMap
LinkedHashMap عبارة عن بنية بيانات تجمع بين القوائم المرتبطة وخرائط التجزئة. في الواقع، يقوم LinkedHashMap بتوسيع فئة HashMap وتنفيذ واجهة الخريطة، ولكن ماذا عن القوائم المرتبطة؟ إعلان LinkedHashMap:
يرث HashMap المرتبط الجديد الخصائص من HashMap (مثل الجدول، وloadFactor، والعتبة، والحجم، وentrySet)، ويحصل أيضًا على خاصيتين خاصتين:
header هو رأس القائمة المرتبطة بشكل مزدوج. أثناء التهيئة، فإنه يشير إلى نفسه
يشير AccessOrder إلى كيفية الوصول إلى العناصر باستخدام المكرر. إذا كان صحيحا، في ترتيب الوصول الأخير. إذا كان خطأ، فسيكون الوصول بالترتيب الذي تم به إدراج العناصر.
تحدد هذه القائمة المرتبطة ترتيب التكرار. عادةً ما يكون هذا هو ترتيب إدخال المفاتيح في الخريطة.
طرق LinkedHashMap
يقوم Object get(Object key) بإرجاع القيمة التي تم تعيين المفتاح المحدد لها، أو يكون فارغًا إذا كانت هذه الخريطة لا تحتوي على تعيين للمفتاح
يزيل void Clear() جميع التعيينات من الخريطة.
boolean يحتوي على مفتاح (مفتاح الكائن) يُرجع صحيحًا إذا تم تعيين العنصر المحدد بواسطة مفتاح واحد أو أكثر
boolean RemoveEldestEntry(Map.Entry eldest) يُرجع صحيحًا إذا قامت الخريطة بإزالة الإدخال الأقدم من الخريطة
Set<Map.Entry<K,V>>entrySet() يُرجع طريقة عرض Set للتعيينات الموجودة في هذه الخريطة
void forEach(BiConsumer<? super K,? super V> action) ينفذ الإجراء المحدد لكل إدخال في هذه الخريطة حتى تتم معالجة جميع الإدخالات أو يلقي الإجراء استثناءً.
يقوم الكائن getOrDefault(Object key, V defaultValue) بإرجاع القيمة التي تم تعيين المفتاح المحدد لها. إذا كانت الخريطة لا تحتوي على تعيين للمفتاح، فسيتم إرجاع القيمة الافتراضية.
تقوم Set<K> keySet() بإرجاع طريقة عرض Set للمفاتيح الموجودة في الخريطة
boolean RemoveEldestEntry(Map.Entry<K,V> eldest) يُرجع صحيحًا إذا كان يجب على هذه الخريطة إزالة الإدخال الأقدم لها
void استبدالAll(BiFunction<? super K,? super V,? Extends V> function) يستبدل كل قيمة إدخال بنتيجة استدعاء الوظيفة المحددة على هذا الإدخال حتى تتم معالجة جميع الإدخالات أو تطرح الوظيفة استثناءً.
تقوم المجموعة<v>values() بإرجاع طريقة عرض المجموعة للقيم الموجودة في الخريطة
مثال LinkedHashMap
importjava.util.LinkedHashMap;importjava.util.Set;importjava.util.Iterator;importjava.util.Map;publicclassHashLinkedListExample{publicstaticvoidmain(String args[]){// LinkedHashMap DeclarationLinkedHashMap<Integer,String> myLinkedHashMap =newLinkedHashMap<Integer,String>();//Adding elements into LinkedHashMap
myLinkedHashMap.put(7,"Johnny");
myLinkedHashMap.put(12,"Rick");
myLinkedHashMap.put(1,"Kyle");
myLinkedHashMap.put(5,"Percy");
myLinkedHashMap.put(85,"Sebastian");// Generate a Set of entriesSet set = myLinkedHashMap.entrySet();// Display and print out the nodes of LinkedHashMapIterator iterator = set.iterator();while(iterator.hasNext()){Map.Entry me =(Map.Entry)iterator.next();System.out.print("key: "+ me.getKey()+" value: "+me.getValue()+"\n");}//print out HashLinkedMap on standard way:System.out.println(myLinkedHashMap);
myLinkedHashMap.put(21,"Ivy");System.out.println(myLinkedHashMap);
myLinkedHashMap.remove(12);System.out.println(myLinkedHashMap);
myLinkedHashMap.put(12,"Ronny");System.out.println(myLinkedHashMap);
myLinkedHashMap.put(1,"Stan");System.out.println(myLinkedHashMap);}}
هنا نقوم بإنشاء LinkedHashMap جديد، مع إضافة خمسة عناصر، ثم طباعته باستخدام المكرر وبطريقة كلاسيكية. كما ترون، LinkedHashMap يحافظ على ترتيب الإدراج. بعد ذلك، نحذف عنصرًا من خريطتنا، ثم نضيف العنصر الجديد وبعد ذلك - عنصر آخر بالمفتاح، وهو موجود بالفعل على الخريطة. فهو يستبدل القيمة القديمة المعينة لهذا المفتاح. نتيجة تشغيل البرنامج:
HashMap وTreeMap وLinkedHashMap هي تطبيقات واجهات الخريطة. HashMap وLinkedHashMap عبارة عن هياكل بيانات تقوم بتجزئة المفاتيح. يستخدم TreeMap الترتيب الطبيعي لمفاتيحه لتنظيم شجرة البحث. طلب:
لا يحتفظ HashMap بأي ترتيب.
يقوم TreeMap بفرز الإدخالات بترتيب تصاعدي للمفاتيح.
يحافظ LinkedHashMap على ترتيب الإدراج.
مفاتيح فارغة:
يسمح HashMap وLinkedHashMap بوجود مفتاح فارغ واحد.
لا يسمح LinkedHashMap بالمفاتيح الفارغة في حالة استخدام المفاتيح للترتيب الطبيعي أو أن المقارنة لا تدعم المقارنة على المفاتيح الفارغة.
لنأخذ مثالًا لخريطة Java يتضمن جميع التطبيقات الثلاثة التي تمت مراجعتها في هذه المقالة:
كما نرى، ترتيب العناصر في HashMap ليس واضحًا، في TreeMap يعتمد على المفاتيح، في LinkedHashMap يتعلق بترتيب الإدراج. إذا حاولنا وضع مفتاح فارغ في LinkHashMap، فسنحصل على NullPointerException، ولكن في LinkedHashMap1، حيث المفاتيح عبارة عن سلسلة، يمكننا القيام بذلك. خريطة التجزئة هي أفضل تطبيق لخريطة الأغراض العامة. فهو يوفر أقصى سرعة بحث، وتخزين سريع، وعمليات استرجاع، ولكن يجب أن تتذكر ترتيبه الفوضوي. ترث خريطة التجزئة المرتبطة مزايا HashMap وتحصل على طلب للمفاتيح. ومع ذلك، فهو يحتوي على قائمة مرتبطة، وهي مكلفة نسبيًا من حيث الذاكرة. إنه أبطأ من HashMap في البحث وأبطأ قليلاً في الإضافة/الإزالة بسبب الحفاظ على القائمة المرتبطة. تقوم الخريطة الشجرية بتخزين المفاتيح مرتبة بترتيب تصاعدي. ومع ذلك، فهو يقدم أداءً عامًا أسوأ من HashMap وLinkedHashMap. لتعزيز ما تعلمته، نقترح عليك مشاهدة درس فيديو من دورة Java الخاصة بنا
GO TO FULL VERSION