المجموعات في Java: ArrayList و HashMap و HashSet
المصفوفة حجمها ثابت، والتطبيقات الحقيقية بياناتها تكبر وتصغر طوال الوقت: سلة مشتريات، قائمة أصدقاء، درجات طلاب. لهذا توفر Java مكتبة المجموعات (Collections). في هذا الدرس ستتقن أهم ثلاثة أنواع فيها: القائمة List، والخريطة Map، والمجموعة Set، وستعرف متى تختار كل واحدة.
كل أمثلة الدرس تحتاج هذا السطر في أول الملف:
import java.util.*;القائمة ArrayList
Section titled “القائمة ArrayList”تعرفت عليها سريعاً في درس المصفوفات. هي قائمة مرتبة يتغير حجمها، وتسمح بتكرار العناصر:
List<String> tasks = new ArrayList<>();tasks.add("المذاكرة");tasks.add("الرياضة");tasks.add(0, "الفطور");System.out.println(tasks);System.out.println(tasks.get(1));System.out.println(tasks.size());
tasks.set(2, "السباحة");tasks.remove("المذاكرة");System.out.println(tasks);System.out.println(tasks.contains("الرياضة"));[الفطور, المذاكرة, الرياضة]المذاكرة3[الفطور, السباحة]falseadd(x)تضيف في الآخر، وadd(0, x)تضيف في موضع محدد.get(i)للقراءة، وset(i, x)للاستبدال، وsize()لعدد العناصر.removeتحذف بالقيمة أو بالموضع، وcontainsتبحث.
الترتيب والمرور
Section titled “الترتيب والمرور”List<Integer> scores = new ArrayList<>(List.of(70, 95, 82, 60));Collections.sort(scores);System.out.println(scores);scores.sort(Comparator.reverseOrder());System.out.println(scores);
int sum = 0;for (int score : scores) { sum += score;}System.out.println("المجموع: " + sum);System.out.println("الأعلى: " + Collections.max(scores));[60, 70, 82, 95][95, 82, 70, 60]المجموع: 307الأعلى: 95List.of(...) تنشئ قائمة ثابتة لا تقبل التعديل، ولذلك وضعناها داخل new ArrayList<>(...) للحصول على نسخة قابلة للتغيير.
الخريطة HashMap
Section titled “الخريطة HashMap”الخريطة (Map) تخزن أزواجاً: مفتاح وقيمته. تماماً مثل دليل الهاتف: تبحث بالاسم فتحصل على الرقم مباشرة، دون المرور على كل الصفحات.
Map<String, Integer> stock = new HashMap<>();stock.put("قلم", 40);stock.put("دفتر", 15);stock.put("قلم", 38);
System.out.println(stock.get("قلم"));System.out.println(stock.get("مسطرة"));System.out.println(stock.getOrDefault("مسطرة", 0));System.out.println(stock.containsKey("دفتر"));System.out.println(stock.size());38null0true2Map<String, Integer>: نوع المفتاح ثم نوع القيمة.put: تضيف زوجاً جديداً، وإذا كان المفتاح موجوداً تستبدل قيمته. المفاتيح لا تتكرر.get: تُرجع القيمة، أوnullإذا لم يوجد المفتاح.getOrDefault: تُرجع قيمة بديلة بدلnull، وهي أكثر أماناً.
المرور على الخريطة
Section titled “المرور على الخريطة”Map<String, Integer> ages = new TreeMap<>();ages.put("Omar", 15);ages.put("Ali", 13);ages.put("Sara", 14);
for (Map.Entry<String, Integer> entry : ages.entrySet()) { System.out.println(entry.getKey() + " = " + entry.getValue());}System.out.println(ages.keySet());Ali = 13Omar = 15Sara = 14[Ali, Omar, Sara]مثال عملي: عدّ التكرارات
Section titled “مثال عملي: عدّ التكرارات”من أشهر استخدامات الخريطة: كم مرة ظهرت كل كلمة؟
String[] votes = { "أحمر", "أزرق", "أحمر", "أخضر", "أحمر", "أزرق" };Map<String, Integer> counts = new TreeMap<>();for (String vote : votes) { counts.put(vote, counts.getOrDefault(vote, 0) + 1);}System.out.println(counts.get("أحمر"));System.out.println(counts.get("أزرق"));System.out.println(counts.get("أخضر"));321في كل مرة نقرأ العدد الحالي للون (أو صفراً إن لم يظهر من قبل)، ونزيده واحداً.
المجموعة HashSet
Section titled “المجموعة HashSet”المجموعة (Set) تشبه القائمة لكنها ترفض التكرار، ولا ترقّم عناصرها:
Set<String> visitors = new TreeSet<>();visitors.add("Sara");visitors.add("Omar");System.out.println(visitors.add("Sara"));System.out.println(visitors);System.out.println(visitors.contains("Omar"));
List<Integer> numbers = List.of(3, 1, 3, 2, 1);Set<Integer> unique = new TreeSet<>(numbers);System.out.println(unique);false[Omar, Sara]true[1, 2, 3]add تُرجع false عندما يكون العنصر موجوداً ولا تضيفه مرة ثانية. وكما في الخرائط: HashSet أسرع لكن بلا ترتيب، و TreeSet ترتب عناصرها. المجموعة مثل سجل حضور: الاسم يُكتب مرة واحدة مهما دخل صاحبه وخرج.
أيها أختار؟
Section titled “أيها أختار؟”| تحتاج إلى | استخدم |
|---|---|
| عناصر مرتبة تصل إليها برقم الموضع | ArrayList |
| البحث عن قيمة بمفتاح (اسم ← رقم) | HashMap |
| عناصر بلا تكرار والتحقق السريع من الوجود | HashSet |
جرّب بنفسك
Section titled “جرّب بنفسك”- أنشئ
ArrayListفيها خمس درجات، واحذف أقل درجة، ثم اطبع المتوسط. - أنشئ
HashMapتربط اسم الدولة بعاصمتها، واطبع عاصمة دولة غير موجودة باستخدامgetOrDefault. - خزّن جملة في متغير، وقسّمها بـ
split(" ")، واستخدمSetلمعرفة عدد الكلمات المختلفة فيها. - تحدٍّ: استخدم
Map<String, List<Integer>>لتخزين عدة درجات لكل طالب، ثم اطبع متوسط كل طالب.
أخطاء شائعة
Section titled “أخطاء شائعة”- الحذف من List الأرقام:
list.remove(1)تحذف العنصر في الموضع 1، لا القيمة 1. لحذف القيمة اكتبlist.remove(Integer.valueOf(1)). - تعديل قائمة ثابتة: الإضافة إلى ناتج
List.of(...)ترميUnsupportedOperationException. - الحذف داخل for-each: حذف عنصر من القائمة أثناء المرور عليها يرمي
ConcurrentModificationException. استخدمremoveIfمثلlist.removeIf(x -> x < 50). - تجاهل null:
map.get(key)قد تُرجعnull، واستخدامها مباشرة في عملية حسابية يسببNullPointerException.
اختبر نفسك
Section titled “اختبر نفسك”سؤال
ماذا يحدث عند استدعاء put بمفتاح موجود مسبقاً في HashMap؟
المفاتيح في الخريطة لا تتكرر، فالقيمة الجديدة تحل محل القديمة.
سؤال
أي مجموعة تختار لتخزين أسماء الزوار دون تكرار؟
Set ترفض التكرار تلقائياً، والتحقق من وجود عنصر فيها سريع جداً.
الخلاصة
Section titled “الخلاصة”ArrayList: قائمة مرتبة يتغير حجمها، وتُرتب بـCollections.sortأوsort.HashMap: أزواج مفتاح وقيمة، معputوgetوgetOrDefaultوentrySet.HashSet: عناصر بلا تكرار. وTreeMapوTreeSetنسخ مرتبة منهما.- المجموعات تخزن كائنات:
Integerوليسint. - مبروك! أنهيت كورس Java. طبّق ما تعلمته في مشروع صغير، فالتطبيق أفضل معلم.