القوائم (Lists) والأطقم (Sets) في جافا: دراسة شاملة ومفصلة
في عالم البرمجة بلغة جافا، تُعدّ هياكل البيانات من الركائز الأساسية التي يُبنى عليها تنظيم البيانات وتحسين أداء البرامج. من بين هذه الهياكل، تأتي القوائم (Lists) والأطقم (Sets) كأكثر الأنواع استخدامًا وتنوعًا في معالجة مجموعات البيانات. هذا المقال يقدم شرحًا وافيًا ومفصلاً عن القوائم والأطقم في جافا، يركز على المفاهيم الأساسية، الأنواع المختلفة، الاستخدامات، الفروقات الجوهرية، وأفضل الممارسات عند التعامل معها.
1. مقدمة إلى هياكل البيانات في جافا
لغة جافا توفر مجموعة كبيرة من هياكل البيانات عبر مكتبة الـ Collections Framework التي تم تصميمها لتنظيم وتخزين البيانات بطرق متنوعة، تلبي متطلبات مختلفة من حيث التكرار، الترتيب، وسرعة الوصول.
القوائم والأطقم هما نوعان من مجموعات البيانات التي تخدم أغراضًا متباينة:
-
القوائم (Lists): مجموعات تسمح بتخزين العناصر بترتيب محدد ويمكن أن تحتوي على عناصر مكررة.
-
الأطقم (Sets): مجموعات لا تسمح بتكرار العناصر، وقد لا تحافظ على ترتيب معين.
2. القوائم (Lists) في جافا
2.1 تعريف القوائم
القائمة هي بنية بيانات تُستخدم لتخزين تسلسل من العناصر التي يمكن الوصول إليها وفقًا لموقعها (الفهرس). يمكن أن تحتوي القوائم على عناصر مكررة، وتدعم عمليات الإضافة، الحذف، والاستعلام عن العناصر بسهولة.
2.2 الواجهة List
في مكتبة الـ Collections Framework، تُعرّف القوائم من خلال واجهة List التي ترث من واجهة Collection. توفر هذه الواجهة مجموعة من الوظائف الأساسية مثل:
-
add(E element): إضافة عنصر. -
get(int index): الحصول على عنصر حسب الفهرس. -
remove(int index): إزالة عنصر بناءً على الفهرس. -
indexOf(Object o): الحصول على أول فهرس يظهر فيه العنصر. -
size(): عدد العناصر.
2.3 الأنواع الرئيسية للقوائم
هناك عدة تطبيقات عملية للواجهة List، أشهرها:
-
ArrayList
تستخدم مصفوفة ديناميكية تحت الغطاء، تدعم الوصول العشوائي السريع (الزمن الثابت للوصول إلى عنصر عبر الفهرس)، لكن عمليات الإضافة أو الحذف في وسط القائمة يمكن أن تكون مكلفة (زمن خطي). -
LinkedList
تمثل القائمة على شكل قائمة مرتبطة (مزدوجة)، توفر سرعة أكبر في عمليات الإضافة والحذف في مواقع مختلفة، لكنها أبطأ في الوصول العشوائي لأنها تحتاج للتنقل عبر العقد. -
Vector
تشبهArrayListلكنها متزامنة (Thread-safe) مما يجعلها أبطأ في البيئات غير المتزامنة.
2.4 مثال عملي على استخدام ArrayList
javaimport java.util.ArrayList;
import java.util.List;
public class ListExample {
public static void main(String[] args) {
List fruits = new ArrayList<>();
fruits.add("تفاح");
fruits.add("موز");
fruits.add("برتقال");
fruits.add("تفاح"); // عنصر مكرر مسموح
System.out.println("قائمة الفواكه: " + fruits);
System.out.println("العنصر عند الفهرس 2: " + fruits.get(2));
System.out.println("موقع أول ظهور لتفاح: " + fruits.indexOf("تفاح"));
fruits.remove("موز");
System.out.println("القائمة بعد إزالة موز: " + fruits);
}
}
3. الأطقم (Sets) في جافا
3.1 تعريف الأطقم
الطقم هو مجموعة من العناصر لا تسمح بتكرار القيم، بمعنى أن كل عنصر فريد ضمن المجموعة. الأطقم غير مرتبة بشكل عام، لكن هناك أنواع تدعم الترتيب.
3.2 الواجهة Set
تعرّف الأطقم في جافا من خلال واجهة Set التي ترث من Collection أيضًا، وتضيف قاعدة تمنع التكرار.
تدعم واجهة Set نفس العمليات الأساسية مثل الإضافة، الحذف، والتحقق من وجود عنصر.
3.3 الأنواع الرئيسية للأطقم
-
HashSet
يعتمد على جدول تجزئة (Hash Table) لتخزين العناصر، لا يحافظ على ترتيب العناصر، ويقدم أداءً ممتازًا في عمليات الإضافة والبحث (متوسط زمن ثابت). -
LinkedHashSet
يحافظ على ترتيب الإدخال بفضل استخدام قائمة مرتبطة إلى جانب جدول التجزئة، مما يجعله مفيدًا حين نرغب في الحفاظ على الترتيب مع تفادي التكرار. -
TreeSet
يحفظ العناصر مرتبة وفقًا لترتيب طبيعي أو مقارنة مخصصة، يعتمد على هيكل بيانات شجرة (Red-Black Tree)، ما يعني أن عمليات الإدخال والبحث تكون في زمن لوغاريتمي.
3.4 مثال عملي على استخدام HashSet
javaimport java.util.HashSet;
import java.util.Set;
public class SetExample {
public static void main(String[] args) {
Set colors = new HashSet<>();
colors.add("أحمر");
colors.add("أزرق");
colors.add("أخضر");
colors.add("أحمر"); // هذا العنصر لن يُضاف لأنه مكرر
System.out.println("محتوى الطقم: " + colors);
boolean hasBlue = colors.contains("أزرق");
System.out.println("هل يحتوي الطقم على أزرق؟ " + hasBlue);
colors.remove("أخضر");
System.out.println("بعد إزالة أخضر: " + colors);
}
}
4. الفرق الأساسي بين القوائم والأطقم
| الخاصية | القوائم (List) | الأطقم (Set) |
|---|---|---|
| التكرار | تسمح بتكرار العناصر | لا تسمح بتكرار العناصر |
| الترتيب | تحافظ على ترتيب الإدخال | لا تحافظ على الترتيب (باستثناء LinkedHashSet) |
| طريقة التخزين | مصفوفة أو قائمة مرتبطة | جدول تجزئة، شجرة، أو قائمة مرتبطة |
| الأداء في البحث | الوصول العشوائي سريع في ArrayList، أبطأ في LinkedList | بحث سريع في HashSet (زمن ثابت)، أبطأ في TreeSet (لوغاريتمي) |
| الاستخدام الشائع | عندما يكون الترتيب مهمًا وتسمح بالتكرار | عند الحاجة إلى تخزين عناصر فريدة فقط |
5. تفاصيل تقنية وأداء القوائم والأطقم
5.1 الأداء في ArrayList و LinkedList
-
ArrayList:
-
إضافة في النهاية: زمن ثابت amortized O(1)
-
إدخال أو حذف في الوسط: زمن خطي O(n) بسبب تحريك العناصر
-
الوصول بالعناصر: زمن ثابت O(1)
-
-
LinkedList:
-
إضافة أو حذف في البداية أو الوسط: زمن ثابت O(1) بعد التنقل للعقدة المطلوبة
-
الوصول بالعناصر: زمن خطي O(n) لأن لا يمكن الوصول مباشرة للعناصر
-
5.2 الأداء في HashSet و TreeSet
-
HashSet:
-
إضافة، حذف، بحث: زمن ثابت amortized O(1)
-
لا يحافظ على الترتيب
-
-
TreeSet:
-
إضافة، حذف، بحث: زمن لوغاريتمي O(log n)
-
يحافظ على ترتيب العناصر
-
5.3 أهمية اختيار الهيكل المناسب
اختيار الهيكل المناسب يعتمد على احتياجات التطبيق:
-
إذا كان الترتيب مهمًا مع السماح بالتكرار، القوائم هي الخيار الأفضل.
-
إذا كان تخزين عناصر فريدة بدون ترتيب كافٍ، HashSet يقدم أفضل أداء.
-
إذا كان التخزين بحاجة لترتيب طبيعي أو مخصص مع ضمان تفرد العناصر، TreeSet هو الحل.
6. تطبيقات عملية للقوائم والأطقم
6.1 استخدام القوائم
-
تخزين بيانات يمكن الوصول إليها حسب الموقع، مثل قائمة أسماء الطلبة في الصف.
-
تنفيذ لوائح انتظار (Queue) أو مكدسات (Stack) عبر LinkedList.
-
التعامل مع بيانات تتطلب تكرار العناصر.
6.2 استخدام الأطقم
-
إزالة التكرار من مجموعة بيانات.
-
التحقق من وجود عنصر معين بسرعة.
-
تمثيل مجموعات رياضية مثل اتحاد، تقاطع، وفرق مجموعتين.
7. العمليات الشائعة على القوائم والأطقم
7.1 عمليات على القوائم
-
الإضافة:
add(E element) -
الحذف:
remove(Object o)أوremove(int index) -
البحث:
contains(Object o),indexOf(Object o) -
التعديل:
set(int index, E element) -
التكرار: استخدام حلقات for التقليدية أو foreach
7.2 عمليات على الأطقم
-
الإضافة:
add(E element) -
الحذف:
remove(Object o) -
البحث:
contains(Object o) -
التكرار: foreach
-
العمليات على المجموعات:
-
الاتحاد:
addAll(Collection extends E> c) -
التقاطع:
retainAll(Collection> c) -
الفرق:
removeAll(Collection> c)
-
8. الجدول المقارن بين ArrayList و LinkedList و HashSet و TreeSet
| الخاصية | ArrayList | LinkedList | HashSet | TreeSet |
|---|---|---|---|---|
| دعم التكرار | نعم | نعم | لا | لا |
| الحفاظ على الترتيب | نعم | نعم | لا | نعم (ترتيب طبيعي أو مخصص) |
| زمن الوصول بالعناصر | ثابت O(1) | خطي O(n) | لا يوجد مفهوم فهرس | لا يوجد مفهوم فهرس |
| زمن الإضافة في النهاية | ثابت amortized O(1) | ثابت O(1) | ثابت amortized O(1) | لوغاريتمي O(log n) |
| زمن الحذف في الوسط | خطي O(n) | ثابت O(1) بعد التنقل | ثابت amortized O(1) | لوغاريتمي O(log n) |
| الاستخدام النموذجي | الوصول العشوائي السريع | إدخال وحذف في المواقع المختلفة | تخزين عناصر فريدة بسرعة | تخزين عناصر مرتبة وفريدة |
9. ملاحظات متقدمة حول القوائم والأطقم في جافا
9.1 التناظر Thread-Safety
-
Vector و Hashtable: متزامنان (Thread-safe) لكن أداؤهما أبطأ.
-
Collections.synchronizedList() و Collections.synchronizedSet(): يمكن استخدامها لتغليف القوائم والأطقم لتصبح متزامنة.
-
CopyOnWriteArrayList و ConcurrentSkipListSet: توفر نسخاً متزامنة أكثر تطوراً وفعالية.
9.2 استخدام Generics
جميع هياكل البيانات في جافا تدعم الـ Generics، مما يسمح بتحديد نوع العناصر المخزنة، ويزيد من الأمان النوعي في الوقت الذي يتم فيه التحقق من الأنواع.
9.3 مقارنة العناصر في الأطقم المرتبة (TreeSet)
في حالة استخدام TreeSet، يجب أن تكون العناصر إما قابلة للمقارنة عبر تنفيذ واجهة Comparable أو يتم تمرير Comparator مخصص عند إنشاء المجموعة، لتحديد كيفية ترتيب العناصر.
10. خلاصة
القوائم والأطقم في جافا تمثل أدوات جوهرية وفعالة لإدارة المجموعات من البيانات حسب متطلبات التكرار والترتيب وأداء العمليات. القوائم تتميز بالترتيب وامكانية التكرار، وتناسب سيناريوهات الوصول العشوائي أو الترتيب المحدد، في حين أن الأطقم تضمن تميز العناصر وتمنع التكرار، مع إمكانيات ترتيب محدودة حسب النوع المستخدم.
فهم هذه المفاهيم بعمق واختيار الهيكل المناسب حسب طبيعة التطبيق يحسن من أداء البرمجيات ويجعلها أكثر تنظيماً ومرونة.
المراجع
-
Oracle. The Java™ Tutorials – Collections. Available at: https://docs.oracle.com/javase/tutorial/collections/
-
Bloch, Joshua. Effective Java, 3rd Edition, Addison-Wesley, 2018.
هذا المقال يقدم مرجعاً شاملاً للقوائم والأطقم في جافا، يواكب أفضل ممارسات البرمجة ويغطي كافة الجوانب التقنية والعملية التي يحتاجها المطورون العرب لتحقيق أقصى استفادة من هذه الهياكل.

