محتويات الدورة

Java / المتوسط / الدرس 7

المجموعات والمساواة والملكية

اختر سلوك القائمة والمجموعة والخريطة وفق عقد السؤال واستدل بشأن الترتيب والمفاتيح المكررة والعناصر المتغيرة والاجتياز الآمن.

وقت القراءة التقريبي: 4 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • اختيار المجموعة وفق الدلالات المطلوبة.
  • شرح المساواة وضمانات ترتيب الاجتياز.
  • تمييز العرض غير القابل للتعديل من النسخة المستقلة.

اختر السلوك قبل التنفيذ

تحفظ List تسلسلاً وتسمح بالتكرار، وتمثل Set عضوية دون عناصر متساوية مكررة، وتربط Map كل مفتاح بقيمة واحدة على الأكثر. هذه عقود دلالية لا حاويات متبادلة. استخدم قائمة لبنود فاتورة مرتبة ومجموعة للمعرفات المزارة وخريطة لعدد المنتجات. حدد قبول null بدلاً من الاعتماد على سياسات تنفيذ مختلفة.

اختر التنفيذ بعد نمط الوصول. تدعم ArrayList الفهرسة والإلحاق بكفاءة في أحمال شائعة، وتختلف كلفة البنى المرتبطة. لا تعد التجزئة بترتيب فرز، وتستخدم الأشجار علاقة ترتيب وتحفظ التجزئة المرتبطة ترتيب لقاء موثقاً. اقرأ العقد قبل جعل الخرج يعتمد على الاجتياز.

فسّر تغير القائمة واللقطات

تنشئ List.of قائمة غير قابلة للتعديل وترفض null، وليست ArrayList قابلة للتوسيع. ينشئ المثال نسخة متغيرة ويلحق قيمة ويطبع الحجمين: يبقى الأصل اثنين وتصبح النسخة ثلاثة. العناصر نصوص ثابتة فالمشاركة السطحية آمنة هنا؛ وتظل كائنات قائمة متغيرة مشتركة بعد نسخها.

تغلف Collections.unmodifiableList قائمة كعرض للقراءة لكن تظهر تغييرات الأصل لاحقاً. توفر List.copyOf لقطة عناصر غير قابلة للتعديل وقت النسخ وفق سياسة null الموثقة. لا يجمد أيهما شبكة كائنات عميقاً. وثّق هل تعيد الواجهة عرضاً حياً أو لقطة أو ملكية متغيرة.

java للنسخة المتغيرة بنية قائمة مستقلة
public class Main {

 public static void main(String[] args) throws Exception {
var original=java.util.List.of("a","b");
var copy=new java.util.ArrayList<>(original);
copy.add("c");
System.out.println(original.size());
System.out.println(copy.size());
 }
}
الناتج المتوقع
2
3

يغير الإلحاق بنية النسخة فقط ويظل النص الثابت مشتركاً.

اجمع القيم بسياسة مفتاح واضحة

تعبر Map.merge عن إدراج عدد ابتدائي أو جمعه مع الموجود. يعد المثال red وblue وred ويستخدم TreeMap لطباعة المفاتيح مرتبة. يكون الناتج حتمياً بعقد التنفيذ لا لأن HashMap صغيرة أظهرت ترتيباً مرغوباً صدفة.

لا ينشئ تكرر المفتاح مدخلاً إضافياً. تستبدل put القيمة وتطبق merge قاعدة محددة. قرر الاستبدال أو الجمع أو الرفض وفق المجال. يجب توافق equals وhashCode لمفاتيح التجزئة وثبات حقول المساواة أثناء التخزين. فضّل معرفاً ثابتاً على كائن عميل متغير كمفتاح.

java عد مع خرج مرتب صراحة
public class Main {

 public static void main(String[] args) throws Exception {
var counts=new java.util.TreeMap<String,Integer>();
for(String color:java.util.List.of("red","blue","red")) {
 counts.merge(color,1,Integer::sum);
}
System.out.println(counts);
 }
}
الناتج المتوقع
{blue=1, red=2}

تجتمع red مرتين تحت مفتاح واحد ويضع الترتيب الطبيعي blue قبلها.

عدل المجموعة عبر الحد الصحيح

قد تكشف المكررات السريعة الفشل تعديلات بنيوية خارج بروتوكولها وتطلق ConcurrentModificationException. ليس ذلك ضمان تزامن وقد يقع بخيط واحد. استخدم حذف المكرر المدعوم أو removeIf أو اجمع نتيجة جديدة بدلاً من تغيير المصدر داخل for محسنة. اختر ما يوضح التصفية.

للمجموعات المتزامنة دلالات مختلفة للاجتياز والتعديل. قد تنسق ConcurrentHashMap عملية مفردة، لكن containsKey ثم put ليست قراراً ذرياً تلقائياً. استخدم واجهة مركبة مناسبة أو مزامنة أوسع. لا تستبدل كل مجموعة بمتزامنة وتترك ثوابت الخطوات المتعددة بلا تفسير.

اختبر الحدود والترتيب المرئي

اختبر الفراغ والتكرار والمفتاح الغائب وتصادم المساواة وسياسة null. إن لزم ترتيب فاختبره كما حُدد ولا تفرز داخل الاختبار لإخفاء تنفيذ غير مرتب. وللعضوية فقط لا تفرض ترتيباً لم يشترطه العقد.

تؤثر الملكية في الصحة والأداء. قد تمنع نسخة صغيرة عند حد الواجهة فئة واسعة من أخطاء التعديل. للبيانات الكبيرة قس ووثق الحاجة إلى عرض أو لقطة ومالك تعديل الأصل. يشرح الاختيار الصحيح معنى العناصر والتعديل والترتيب وكلفة العمليات الفعلية.

الأخطاء الشائعة وإصلاحها

UnsupportedOperationException

لماذا يحدث؟
حاولت الشيفرة تعديل مجموعة غير قابلة للتعديل.
كيف تصلحه؟
استخدم نسخة متغيرة مملوكة أو نتيجة جديدة.
كيف تتجنب تكراره؟
وثق قابلية التعديل.

ConcurrentModificationException

لماذا يحدث؟
استُخدم بروتوكولان غير متوافقين للاجتياز والتعديل.
كيف تصلحه؟
استخدم removeIf أو حذف المكرر أو مجموعة جديدة.
كيف تتجنب تكراره؟
اختبر عدة عناصر مطابقة.

A map key cannot be found after editing it

لماذا يحدث؟
تغيرت حالة المساواة والتجزئة للمفتاح المخزن.
كيف تصلحه؟
استخدم مفتاحاً ثابتاً أو أزل وأعد الإدراج بسياسة سليمة.
كيف تتجنب تكراره؟
راجع equals وhashCode معاً.

اختبر فهمك

1. لماذا لا يجمد نسخ List<MutableItem> العناصر؟

اعرض الحل المشروح

تنسخ البنية وتبقى مراجع العناصر مشتركة. استخدم أنواعاً ثابتة أو نسخ عناصر دفاعية أو عقد مشاركة واضحاً إن وجب منع تغيير الداخل.

2. يجب طباعة رموز المنتجات مرتبة مع أعدادها. اختر تمثيلاً.

اعرض الحل المشروح

تجمع TreeMap وتطبع وفق مقارنها، أو افرز المدخلات عند العرض. لا تعتمد اجتياز HashMap وحدد هل الترتيب نصي أو خاص بالمجال.

أهم ما تعلمته

  • تمثل الواجهات تسلسلاً أو عضوية أو ربطاً.
  • عدم قابلية التعديل لا يعني الثبات العميق.
  • يحتاج الترتيب والذرية المركبة عقداً صريحاً.

المراجع الرسمية