الإطار Collection في جافا | Java Collections

الإطار Collection في جافا | Java Collections

في الإصدار 1 في جافا, تم بناء بعض الكلاسات التي تهتم بطريقة تخزين البيانات في الذاكرة أثناء تشغيل البرنامج و منها ما ذكرنا في الدرس السابق.

في الإصدار 2 في جافا, تم تطوير مبادئ الـ Data Structure بشكل ملحوظ حيث تم إضافة مجموعة كبيرة من الكلاسات (Classes) و الإنترفيسات (Interfaces) بشكل منظم ضمن مجموعات ( Collections ). كل مجموعة منهم تمثل مبدأ معين في طريقة تخزين البيانات في الذاكرة وقت تشغيل البرنامج.

ميزة أخرى يقدمها لك الإطار Collection ألا و هي المزامنة ( Synchronization ). ستعرف أهمية المزامنة لاحقاً في هذا الدرس.


بناء الـ Collections في جافا

الإطار Collection بني بشكل هرمي كالتالي:

  • كل فكرة أساسية فيه تمثل بإنترفيس.

  • و كل طريقة يمكن استخدامها لتنفيذ هذه الفكرة تمثل بكلاس.


الإنترفيس Collection هو أساس كل Collection موجودة في هذا الإطار.
كل إنترفيس يرث مباشرةً من الإنترفيس Collection يمثل Collection مختلفة.

الصورة التالية توضح طريقة بناء الإطار Collection.

كلاسات هياكل البيانات في جافا

ملاحظة

بعض الكلاسات التي تم تعريفها في الإصدار 1, هي نفسها التي ستراها في الإصدار 2 و التي وضعت في Collection معينة.
في الدرس السابق, صحيح أننا شرحنا كلاسات الـ Data Structure التي وجدت في أول إصدار من لغة جافا, لكننا شرحناها كما هي الآن في آخر إصدار منها.

الإنترفيسات الموجودة في الإطار Collection

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

الجدول التالي يحتوي على جميع الإنترفيسات الموجودة في الـ Collection.

الإنترفيس مع تعريفه
public interface Collection الإنترفيسCollection مصمم بشكل عام لاحتواء الأشياء المشتركة في جميع الـ Collection.
إذاً هو الأساس لأي إنترفيس يمثل Collection حيث أن جميع الـ Collection ترث منه.
تابع القراءة »
public interface List الإنترفيس List يرث من الإنترفيس Collection. تم بناءه لتخزين مجموعة من العناصر كما لو أنه مصفوفة ليس لها حجم محدد.
تابع القراءة »
public interface Set الإنترفيس Set يرث من الإنترفيس Collection.
الفرق الأساسي بينه و بين الإنترفيس List هو أنه لا يمكنه تخزين نفس القيمة في أكثر من عنصر. إذاً هنا لا يمكن وجود نفس القيمة في أكثر من عنصر.
هذا الإنترفيس مفيد في العلميات الحسابية, حيث أن وجود عناصر لا تحمل نفس القيمة, يتيح لك مقارنة قيمهم بشكل منطقي حتى و لو كانوا مختلفين في النوع.
تابع القراءة »
public interface SortedSet الإنترفيس SortedSet يرث من الإنترفيس Set. تم بناءه لتخزين العناصر بترتيب تصاعدي ( Ascending ), أي من الأصغر إلى الأكبر.
كما أنه يحتوي على دوال جديدة غير موجودة في الإنترفيس Set.
تابع القراءة »
public interface Comparator الإنترفيس Comparator مصمم لمقارنة قيم الكائنات.
يعتمد عليه كل إنترفيس يقوم بترتيب الكائنات التي يتم إدخلها فيه, سواء كان ترتيباً حسب القيمة أو ترتيباً أبجدياً.
تابع القراءة »
public interface Iterator الإنترفيس Iterator يستخدم لتخزين عناصر متتالية موجودة في أي كائن دفعة واحدة.
بعدها يمكن إرجاع هذه العناصر واحداً تلو الآخر.
ينصح باستخدام هذا الإنترفيس بدل استخدام الإنترفيس Enumeration.
تابع القراءة »
public interface ListIterator الإنترفيس ListIterator يرث من الإنترفيس Iterator, و يملك دوال إضافية للتعامل مع العناصر المخزنة.
تابع القراءة »

الكلاسات الموجودة في الإطار Collection

الكلاس مع تعريفه
public class ArrayList الكلاس ArrayList يستخدم لإنشاء مصفوفات متطورة مقارنةً مع المصفوفات العادية Arrays, حيث يوفر لك مجموعة من الدوال التي تمكنك من البحث فيها, التشييك على عناصرها, إضافة عناصر جديدة, حذف عناصر منها, و معالجة أكثر من عنصر فيها في نفس الوقت إلخ..
أهم ميزة في المصفوفات التي نوعها ArrayList هي أن عدد العناصر فيها غير ثابت, حيث أنه يزيد عند إضافة عنصر جديد فيها و ينقص عند حذف عنصر منها بشكل تلقائي, و هذه الميزة غير موجودة في المصفوفات العادية.
تابع القراءة »
public class LinkedList يشبه الكلاس ArrayList من حيث الفكرة. و هو يحتوي على دوال إضافية غير موجودة فيه.
تابع القراءة »
public class HashSet الكلاس HashSet يستخدم لتخزين عناصر متتالية, دون مراعاة أي دقة في ترتيب هذه العناصر, كما أنه يسمح بتخزين القيمة null.
لكنه لا يسمح بتخزين أكثر من عنصر عندهم نفس القيمة, فتجد كل عنصر فيه يملك قيمة مختلفة.
السبب الوحيد الذي قد يجعلك تستخدم هذا الكلاس هو سرعته العالية في التخزين مقارنة مع باقي الكلاسات الموجودة في المجموعة Set.
تابع القراءة »
public class LinkedHashSet الكلاس LinkedHashSet يرث من الكلاس HashSet تم تصميمه فقط للحفاظ على ترتيب العناصر التي يتم إدخالها فيه.
و هو يملك نفس الأشياء التي يملكها الكلاس HashSet.
تابع القراءة »
public class TreeSet الكلاس TreeSet يعتبر الكلاس الأكثر تطوراً بين كلاسات المجموعة Set, و هو يستخدم لتخزين عناصر متتالية, و ترتيبهم بالطريقة التي تريد, كما أنه يسمح بتخزين القيمة null, لكنه لا يسمح بتخزين أكثر من عنصر عندهم نفس القيمة, فتجد كل عنصر فيه يملك قيمة مختلفة. و هو يحتوي على دوال أخرى تسهل طريقة الوصول للعناصر.
تابع القراءة »

الإنترفيسات الموجودة في الإطار Map

الجدول التالي يحتوي إنترفيسات لا ترث من الإنترفيس Collection, لكنها مهمة جداً حيث أن بعضها يوفر لك طرق تخزين لا تتوافر في الإطار Collection, و بعضها يستخدم للتعامل مع الكلاسات الموجودة في الإطار Collection.

الإنترفيس مع تعريفه
public interface Map الإنترفيس Map يتيح لك تخزين العناصر بشكل Key / Value.
هنا كل عنصر يتم تخزينه يملك كائنين: الأول عبارة عن مفتاح ( key ) و الثاني عبارة قيمة ( value ).
تابع القراءة »
public interface SortedMap هذا الإنترفيس يرث من الإنترفيس Map, تم بناءه لتخزين العناصر بشكل Key / Value.
هنا يتم ترتيب العناصر حسب الـ key بشكل تصاعدي, من الأصغر إلى الأكبر.
تابع القراءة »

الكلاسات الموجودة في المجموعة Map

الكلاس مع تعريفه
public class HashMap الكلاس HashMap يستخدم لتخزين العناصر بشكل Key / Value حيث يتم إعطاء مفتاح لكل قيمة يتم تخزينها بداخل الـ HashMap.
إذاً الـ HashMap كأنه جدول يتألف من عامودين, الأول يحتوي المفاتيح ( Keys ) و الثاني يحتوي على القيم ( Values ).
تابع القراءة »
public class LinkedHashMap الكلاس LinkedHashMap يرث من الكلاس HashMap تم تصميمه فقط للحفاظ على ترتيب العناصر التي يتم إدخالها فيه.
تابع القراءة »
public class TreeMap الكلاس TreeMap يعتبر الكلاس الأكثر تطوراً بين كلاسات المجموعة Tree, و هو يستخدم لترتيب العناصر في الذاكرة بشكل تصاعدي Ascending نسبة للـ keys. و هو يحتوي على دوال أخرى تسهل طريقة الوصول للعناصر.
تابع القراءة »

مجموعة الخوارزميات Algorithms Collection

الكلاس Collection يحتوي على دوال ثابتة نوعها static. هذه الدوال تساعد كثيراً في الوصول إلى العناصر و التلاعب بها سواء كنت تتعامل مع الكلاسات التي ترث من الإنترفيس Collection أو مع الكلاسات التي ترث من الإنترفيس Map.

إذاً هذه الدوال تغنيك عن كتابة خوارزميات صعبة و معقدة, لذلك سميت مجموعة الخوارزميات ( Algorithms Collection ).

لمزيد من التفاصيل حول مجموعة الخوارزميات تابع القراءة »

__________&&&______;&&&___________;&&&&________; __________&&&______;&&&___________;&&&&________;

 الإنترفيس Collection في جافا

مقدمة الإنترفيس Collection في جافا

الإنترفيسCollection مصمم بشكل عام لاحتواء الأشياء المشتركة في جميع الـ Collection.
إذاً هو الأساس لأي إنترفيس يمثل Collection حيث أن جميع الـ Collection ترث منه.

بما أن جميع الـ Collection ترث منه, ننصحك بفهم دواله بشكل جيد لأنها ستمر معك في كل كلاس موجود في الـ Collection.
في حال قمت باستدعاء أي دالة فيه بشكل خاطئ سيتم رمي الإستثناء UnsupportedOperationException

دوال الإنترفيس Collection في جافا

الجدول التالي يحتوي على دوال الإنترفيس Collection.

الدالة مع تعريفها
public boolean add(Object o) تضيف كائن جديد في الكائن الذي قام باستدعائها.
ترجع true إذا تمت الإضافة بنجاح.
public boolean addAll(Collection c) تضيف جميع العناصر الموجودة في الكائن c بالترتيب في آخر الكائن الذي قام باستدعائها.
ترجع true إذا تمت الإضافة بنجاح.
public void clear() تمسح جميع العناصر الموجودة في الكائن الذي قام باستدعائها.
public boolean contains(Object obj) ترجع true إذا كان الكائن الذي قام باستدعائها يحتوي على الكائن الذي نضعه لها كـ Argument.
public boolean containsAll(Collection c) ترجع true إذا كان الكائن الذي قام باستدعائها يحتوي على جميع العناصر الموجودة في الكائن c.
public boolean equals(Object obj) ترجع true في حال كان الكائن الذي قام باستدعائها يتطابق مع الكائن الذي نمرره لها كـ Argument.
public int hashCode() ترجع الـ Hash Code للكائن الذي قام باستدعائها.
public boolean isEmpty() ترجع true في حال كان الكائن الذي قام باستدعائها فارغاً.
public Iterator iterator() ترجع كائن نوعه Iterator يحتوي على جميع عناصر الكائن الذي قام باستدعائها.
public boolean remove(Object o) تحذف أول عنصر يتم إيجاده في الكائن الذي قام باستدعائها في حال كان يتطابق مع الكائن الذي نمرره لها كـ Argument.
ترجع true إذا تم حذف العنصر بنجاح.
public boolean removeAll(Collection c) تحذف مجموعة متتالية من العناصر الموجود في الكائن الذي قام باستدعائها في حال كانت تتطابق مع كائن الـ Collection الذي نمرره لها كـ Argument.
ترجع true إذا تم حذف جميع العناصر بنجاح.
public boolean retainAll(Collection c) تبقي عناصر الكائن الذي قام باستدعائها في حال كانت موجودة في عناصر الكائن c الذي نمرره لها كـ Argument, و تحذف جميع العناصر الأخرى.
public int size() ترجع عدد العناصر الموجودة في كائن الـ Interface.
public Object[] toArray() ترجع مصفوفة نوعها Object تحتوي على جميع العناصر الموجودة في الكائن الذي قام باستدعائها.
public Object[] toArray(Object array[]) ترجع مصفوفة نوعها Object تحتوي على جميع عناصر الكائن الذي قام باستدعائها و التي عندها نفس نوع المصفوفة array التي نمررها لها كـ Argument.
مثال شامل

في المثال التالي قمنا بإنشاء ثلاث كائنات من ثلاث كلاسات مختلفة ترث من الإنترفيس Collection.
لاحظ أننا استخدمنا الدالة add() التي ورثتها الكائنات في الأساس من الإنترفيس Collection.

مثال
Main.java
                    import java.util.*;               // util هنا قمنا باستدعاء جميع الكلاسات و الإنترفيسات الموجودة في الحزمة

                    public class Main {

                    public static void main(String[] args) {

                    // وضعنا فيه ثلاث كائنات o1 إسمه Vector هنا قمنا بإنشاء كائن من الكلاس
                    Vector o1 = new Vector();
                    o1.add("A");
                    o1.add("B");
                    o1.add("C");

                    // وضعنا فيه ثلاث كائنات o2 إسمه HashSet هنا قمنا بإنشاء كائن من الكلاس
                    HashSet o2 = new HashSet();
                    o2.add("A");
                    o2.add("B");
                    o2.add("C");

                    // وضعنا فيه ثلاث كائنات o3 إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
                    LinkedList o3 = new LinkedList();
                    o3.add("A");
                    o3.add("B");
                    o3.add("C");

                    // o3 و o2 و o1 هنا قمنا بعرض محتويات الكائنات
                    System.out.println("Vector elements:     " + o1);
                    System.out.println("HashSet elements:    " + o2);
                    System.out.println("LinkedList elements: " + o3);

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    Vector elements:     [A, B, C]
                    HashSet elements:    [A, B, C]
                    LinkedList elements: [A, B, C] 
                  
__________&&&______;&&&___________;&&&&________;

 الإنترفيس List في جافا

مقدمة الإنترفيس List في جافا

الإنترفيس List يرث من الإنترفيس Collection, و هو عبارة عن Collection فكرتها تخزين مجموعة متتالية من العناصر.


نظرة عامة الإنترفيس List في جافا

  • بشكل عام, يستخدم لإنشاء مصفوفة ليس لها حجم محدد.

  • العناصر يمكن إضافتها في أمكان محددة فيه, و يمكن الوصول إليها بواسطة أرقام الـ indices.

  • يمكنه إحتواء عناصر متكررة, أي يمكنه تخزين نفس القيمة فيه أكثر من مرة.

  • يملك دواله الخاصة إضافةً إلى الدوال التي ورثها من الإنترفيس Collection.

  • بعض الدوال التي يملكها ترمي الإستثناء UnsupportedOperationException إذا تم استخدامهم بطريقة خاطئة.

  • يرمى الإستثناء ClassCastException في حال كان لا يمكن تحويل نوع الكائن إلى نوع آخر.

دوال الإنترفيس List في جافا

الجدول التالي يحتوي على دوال الإنترفيس List.

الدالة مع تعريفها
void add(int index, Object obj) تضيف عنصر جديد في مكان محدد في الكائن الذي قام باستدعائها.
  • obj هو الكائن الذي سيضاف.

  • index هو رقم الـ index الذي سيضاف فيه الكائن obj.

boolean addAll(int index, Collection c) تضيف جميع عناصر كائن الـ Collection في مكان محدد في الكائن الذي قام باستدعائها.
ترجع true إذا تمت الإضافة بنجاح.
  • c هو مجموعة الكائنات التي ستضاف.

  • index هو رقم الـ index الذي سيضاف فيه الكائن c.

Object get(int index) ترجع الكائن الموجود في الـ index الذي نمرره لها كـ Argument.
int indexOf(Object element) تبحث في الكائن الذي قام باستدعائها عن مكان الكائن الذي نمرره لها كـ Argument.
ترجع Index أول عنصر يحتوي على الكائن المطلوب في حال وجود نفس الكائن في أكثر من عنصر.
ترجع 1- في حال عدم إيجاد الكائن المطلوب.
int lastIndexOf(Object element) تبحث في الكائن الذي قام باستدعائها عن مكان الكائن الذي نمرره لها كـ Argument.
ترجع رقم آخر Index يحتوي على الكائن المطلوب في حال وجود نفس الكائن في أكثر من عنصر.
ترجع 1- في حال عدم إيجاد الكائن المطلوب.
Object remove(int index) تحذف عنصر محدد من عناصر الكائن الذي قام باستدعائها.
Object set(int index, Object element) تبدل قيمة عنصر محدد من عناصر الكائن الذي قام باستدعائها بقيمة جديدة, و ترجع القيمة السابقة.
  • index هو رقم index العنصر الذي سيتم تبديل قيمته.

  • element هو الكائن الجديد الذي سيوضع كقيمة للعنصر.

List subList(int start, int end) ترجع كائن نوعه List يمثل العناصر الموجودة في الكائن الذي قام باستدعائها إبتداءاً من start وصولاً إلى ما قبل end.
ListIterator listIterator() ترجع كائن نوعه ListIterator يحتوي على جميع عناصر الكائن الذي قام باستدعائها.
ListIterator listIterator(int start) ترجع كائن نوعه ListIterator يحتوي على جميع عناصر الكائن الذي قام باستدعائها إبتداءاً من start.
مثال شامل

في المثال التالي قمنا بإنشاء ثلاث كائنات من ثلاث كلاسات مختلفة ترث من الإنترفيس List.
لاحظ أننا استخدمنا الدالة add() التي ورثتها الكائنات في الأساس من الإنترفيس List.

Main.java
                    import java.util.*;   // util هنا قمنا باستدعاء جميع الكلاسات و الإنترفيسات الموجودة في الحزمة

                    public class Main {

                    public static void main(String[] args) {

                    // وضعنا فيه ثلاث كائنات o1 إسمه Vector هنا قمنا بإنشاء كائن من الكلاس
                    Vector o1 = new Vector();
                    o1.add("A");
                    o1.add("B");
                    o1.add("C");

                    // وضعنا فيه ثلاث كائنات o2 إسمه ArrayList هنا قمنا بإنشاء كائن من الكلاس
                    ArrayList o2 = new ArrayList();
                    o2.add("A");
                    o2.add("B");
                    o2.add("C");

                    // وضعنا فيه ثلاث كائنات o3 إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
                    LinkedList o3 = new LinkedList();
                    o3.add("A");
                    o3.add("B");
                    o3.add("C");

                    // o3 و o2 و o1 هنا قمنا بعرض محتويات الكائنات
                    System.out.println("Vector elements:     " + o1);
                    System.out.println("ArrayList elements:  " + o2);
                    System.out.println("LinkedList elements: " + o3);

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    Vector elements:     [A, B, C]
                    ArrayList elements:  [A, B, C]
                    LinkedList elements: [A, B, C]
                  
__________&&&______;&&&___________;&&&&________;

 الإنترفيس Set في جافا

مقدمة الإنترفيس Set في جافا

الإنترفيس Set يرث من الإنترفيس Collection, و هو عبارة عن Collection فكرتها تخزين مجموعة متتالية من العناصر, كل عنصر فيها يملك قيمة مختلفة.

الفرق الأساسي بينه و بين الإنترفيس List هو أنه لا يمكنه تخزين نفس القيمة في أكثر من عنصر. إذاً هنا لا يمكن وجود نفس القيمة في أكثر من عنصر.

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


نظرة عامة الإنترفيس Set في جافا

  • بشكل عام, يستخدم لإنشاء مصفوفة ليس لها حجم محدد.

  • لا يمكنه إحتواء عناصر متكررة, أي لا يمكنه تخزين كائنين عندهم نفس النوع و نفس القيمة.

  • يملك الدوال التي ورثها من الإنترفيس Collection فقط.

  • بعض الدوال التي يملكها ترمي الإستثناء UnsupportedOperationException إذا تم استخدامهم بطريقة خاطئة.

  • يرمى الإستثناء ClassCastException في حال كان لا يمكن تحويل نوع الكائن إلى نوع آخر.

دوال الإنترفيس Set في جافا

الجدول التالي يحتوي على دوال الإنترفيس Set.

الدالة مع تعريفها
public boolean add(Object o) تضيف كائن جديد في الكائن الذي قام باستدعائها.
ترجع true إذا تمت الإضافة بنجاح.
public boolean addAll(Collection c) تضيف جميع العناصر الموجودة في الكائن c بالترتيب في آخر الكائن الذي قام باستدعائها.
ترجع true إذا تمت الإضافة بنجاح.
public void clear() تمسح جميع العناصر الموجودة في الكائن الذي قام باستدعائها.
public boolean contains(Object obj) ترجع true إذا كان الكائن الذي قام باستدعائها يحتوي على الكائن الذي نضعه لها كـ Argument.
public boolean containsAll(Collection c) ترجع true إذا كان الكائن الذي قام باستدعائها يحتوي على جميع العناصر الموجودة في الكائن c.
public boolean equals(Object obj) ترجع true في حال كان الكائن الذي قام باستدعائها يتطابق مع الكائن الذي نمرره لها كـ Argument.
public int hashCode() ترجع الـ Hash Code للكائن الذي قام باستدعائها.
public boolean isEmpty() ترجع true في حال كان الكائن الذي قام باستدعائها فارغاً.
public Iterator iterator() ترجع كائن نوعه Iterator يحتوي على جميع عناصر الكائن الذي قام باستدعائها.
public boolean remove(Object o) تحذف أول عنصر يتم إيجاده في الكائن الذي قام باستدعائها في حال كان يتطابق مع الكائن الذي نمرره لها كـ Argument.
ترجع true إذا تم حذف العنصر بنجاح.
public boolean removeAll(Collection c) تحذف مجموعة متتالية من العناصر الموجود في الكائن الذي قام باستدعائها في حال كانت تتطابق مع كائن الـ Collection الذي نمرره لها كـ Argument.
ترجع true إذا تم حذف جميع العناصر بنجاح.
public boolean retainAll(Collection c) تبقي عناصر الكائن الذي قام باستدعائها في حال كانت موجودة في عناصر الكائن c الذي نمرره لها كـ Argument, و تحذف جميع العناصر الأخرى.
public int size() ترجع عدد العناصر الموجودة في كائن الـ Interface.
public Object[] toArray() ترجع مصفوفة نوعها Object تحتوي على جميع العناصر الموجودة في الكائن الذي قام باستدعائها.
public Object[] toArray(Object array[]) ترجع مصفوفة نوعها Object تحتوي على جميع عناصر الكائن الذي قام باستدعائها و التي عندها نفس نوع المصفوفة التي نمررها لها كـ Argument.
مثال شامل

في المثال التالي قمنا بإنشاء ثلاث كائنات من ثلاث كلاسات مختلفة ترث من الإنترفيس Set.
لاحظ أننا استخدمنا الدالة add() التي ورثتها الكائنات في الأساس من الإنترفيس Set.

Main.java
                    import java.util.*;   // util هنا قمنا باستدعاء جميع الكلاسات و الإنترفيسات الموجودة في الحزمة

                    public class Main {

                    public static void main(String[] args) {

                    // وضعنا فيه ثلاث كائنات o1 إسمه TreeSet هنا قمنا بإنشاء كائن من الكلاس
                    TreeSet o1 = new TreeSet();
                    o1.add(1);
                    o1.add(2);
                    o1.add(3);

                    // وضعنا فيه ثلاث كائنات o2 إسمه HashSet هنا قمنا بإنشاء كائن من الكلاس
                    HashSet o2 = new HashSet();
                    o2.add(4);
                    o2.add(5);
                    o2.add(6);

                    // وضعنا فيه ثلاث كائنات o3 إسمه LinkedHashSet هنا قمنا بإنشاء كائن من الكلاس
                    LinkedHashSet o3 = new LinkedHashSet();
                    o3.add(7);
                    o3.add(8);
                    o3.add(9);

                    // o3 و o2 و o1 هنا قمنا بعرض محتويات الكائنات
                    System.out.println("TreeSet elements:       " + o1);
                    System.out.println("HashSet elements:       " + o2);
                    System.out.println("LinkedHashSet elements: " + o3);

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    TreeSet elements:       [1, 2, 3]
                    HashSet elements:       [4, 5, 6]
                    LinkedHashSet elements: [7, 8, 9] 
                  
__________&&&______;&&&___________;&&&&________;

 الإنترفيس SortedSet في جافا

مقدمة الإنترفيس SortedSet في جافا

الإنترفيس SortedSet يرث من الإنترفيس Set. تم بناءه لتخزين العناصر بترتيب تصاعدي ( Ascending ).

إذاً في حال كانت قيم العناصر تمثل أرقام, عندها يتم ترتيبهم من العدد الأصغر إلى العدد الأكبر.
في حال كانت قيم العناصر تمثل نصوص أو كلمات أو أحرف, عندها يتم ترتيبهم ترتيباً أبجدياً.

كما أنه يحتوي على دوال جديدة غير موجودة في الإنترفيس Set.


نظرة عامة الإنترفيس SortedSet في جافا

  • بشكل عام, يستخدم لإنشاء مصفوفة ليس لها حجم محدد.

  • لا يمكنه إحتواء عناصر متكررة, أي لا يمكنه تخزين كائنين عندهم نفس النوع و نفس القيمة.

  • يتم ترتيب العناصر فيه بشكل تلقائي بترتيب تصاعدي حسب قيمهم.

  • يملك دواله الخاصة إضافةً إلى الدوال التي ورثها من الإنترفيس Set.

  • بعض الدوال التي يملكها ترمي الإستثناء UnsupportedOperationException إذا تم استخدامهم بطريقة خاطئة.

  • يرمى الإستثناء ClassCastException في حال كان لا يمكن تحويل نوع الكائن إلى نوع آخر.

  • يرمى الإستثناء NullPointerException في حال تم إضافة القيمة null فيه لأنه لا يقبل القيمة null.

دوال الإنترفيس SortedSet في جافا

الجدول التالي يحتوي على دوال الإنترفيس SortedSet.

الدالة مع تعريفها
public Object first() ترجع قيمة أول عنصر موجود في الكائن الذي قام باستدعائها.
ملاحظة: قيمته ستكون أصغر قيمة لأن العناصر في هذا الكائن تترتب فيه بشكل تصاعدي.
public Object last() ترجع قيمة آخر عنصر موجود في الكائن الذي قام باستدعائها.
ملاحظة: قيمته ستكون أكبر قيمة لأن العناصر في هذا الكائن تترتب فيه بشكل تصاعدي.
public SortedSet headSet(Object end) ترجع كائن نوعه SortedSet يحتوي على جميع عناصر الكائن الذي قام باستدعائها الموجودة قبل الكائن end.
public SortedSet tailSet(Object Start) ترجع كائن نوعه SortedSet يحتوي على جميع عناصر الكائن الذي قام باستدعائها إبتداءاً من الكائن start حتى آخر عنصر موجود فيه.
public SortedSet subSet(Object start, Object end) ترجع كائن نوعه SortedSet يحتوي على جميع عناصر الكائن الذي قام باستدعائها إبتداءاً من الكائن start وصولاً إلى الكائن end.
public Comparator comparator() ترجع كائن نوعه Comparator يمثل الإنترفيس المستخدم في مقارنة العناصر.
ترجع null في حال لم تقم بتغيير الإنترفيس الإفتراضي.
مثال شامل

في المثال التالي قمنا بإنشاء كائن من الكلاس TreeSet و الذي يرث من الإنترفيس SortedSet.
قمنا باستخدام جميع دواله التي ذكرناها في الجدول السابق.

مثال
Main.java
                    import java.util.*;   // util هنا قمنا باستدعاء جميع الكلاسات و الإنترفيسات الموجودة في الحزمة

                    public class Main {

                    public static void main(String[] args) {

                    // ts إسمه TreeSet هنا قمنا بإنشاء كائن من الكلاس
                    TreeSet ts = new TreeSet();

                    // تعمدنا عدم ترتيب القيم من الأصغر إلى الأكبر حتى ترى أنه سيرتبهم بشكل تلقائي .ts هنا قمنا بإضافة 5 قيم في الكائن
                    ts.add(4);
                    ts.add(2);
                    ts.add(5);
                    ts.add(3);
                    ts.add(1);

                    // لاحظ أنه قام بترتيبهم من الأصغر إلى الأكبر .ts هنا قمنا بعرض عناصر الكائن
                    System.out.println("All elements : " + ts);

                    // ts هنا قمنا بعرض أول عنصر موجود في الكائن
                    System.out.println("First element: " + ts.first());

                    // ts هنا قمنا بعرض آخر عنصر موجود في الكائن
                    System.out.println("Last element : " + ts.last());

                    // '3' الموجودة قبل العنصر الذي يملك القيمة ts هنا قمنا بعرض جميع عناصر الكائن
                    System.out.println("headSet(3)   : " + ts.headSet(3));

                    // '3' إبتداءاً من العنصر الذي يملك القيمة ts هنا قمنا بعرض جميع عناصر الكائن
                    System.out.println("tailSet(3)   : " + ts.tailSet(3));

                    // 'إبتداءاً من العنصر الذي يملك القيمة '1' وصولاً إلى ما قبل العنصر الذي يملك القيمة '4 ts هنا قمنا بعرض جميع عناصر الكائن
                    System.out.println("Subset(1,4)  : " + ts.subSet(1, 4));

                    // هنا قمنا بعرض الإنترفيس المستخدم في مقارنة العناصر
                    System.out.println("Comparator() : " + ts.comparator());

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    All elements : [1, 2, 3, 4, 5]
                    First element: 1
                    Last element : 5
                    headSet(3)   : [1, 2]
                    tailSet(3)   : [3, 4, 5]
                    Subset(1,4)  : [1, 2, 3]
                    Comparator() : null 
                  
__________&&&______;&&&___________;&&&&________;

 الإنترفيس Comparator في جافا

مقدمة الإنترفيس Comparator في جافا

الإنترفيس Comparator مصمم لمقارنة قيم الكائنات.

يعتمد عليه كل إنترفيس يقوم بترتيب الكائنات التي يتم إدخلها فيه, سواء كان ترتيباً حسب القيمة أو ترتيباً أبجدياً.
فمثلاً, عند إنشاء كائن من الكلاس TreeSet نجد العناصر فيه تم ترتيبها بشكل تصاعدي حسب قيمهم في حال كانت عناصره عبارة عن أرقام, أو ترتيباً أبجدياً في حال كانت عناصره تمثل نصوص.

دوال الإنترفيس Comparator في جافا

الجدول التالي يحتوي على دوال الإنترفيس Comparator.

الدالة مع تعريفها
public int compare(Object obj1, Object obj2) تقارن الكائن obj1 و الكائن obj2 من أجل ترتيبهم.
يجب أن تفعل لها Override لتحدد كيف تريدها أن تقارن الكائنين, أي على أي أساس سيتم ترتيبهم.
فمثلاً يمكنك جعلها تقارن عدد أحرف الكائنين في حال كانوا عبارة عن نصوص, و يمكنك جعلها تقارن قيمة الكائنين في حال كانوا عبارة عن أرقام.
public boolean equals(Object obj) ترجع true في حال كان الكائن الموضوع فيها كـ Argument يساوي الكائن الذي قام باستدعائها.
مثال شامل

في المثال التالي قمنا بإنشاء كلاس إسمه NumbersComparator يفعل implements للإنترفيس Comparator.
إذاً على الكلاس NumbersComparator أن يفعل Override للدالة compare() حتى تقارن الأرقام بالطريقة التي نريد.

الدالة compare() عندها باراميترين من النوع Object. يجب جعلها تقارن أي كائنين نمررهما لها بالطريقة التي نريد.

سنجعلها تقارن أي رقمين كالتالي:

  • ترجع 0 في حال كانا متساوييان.

  • ترجع 1 في حال كانت قيمة الكائن obj1 أكبر من قيمة الكائن obj2.

  • ترجع 1- في حال كانت قيمة الكائن obj1 أصغر من قيمة الكائن obj2.

في الأخير قمنا بإنشاء كلاس إسمه Main لتجربة الدالة compare() فيه.


NumbersComparator.java
                    import java.util.Comparator;                              // Comparator هنا قمنا باستدعاء الإنترفيس

                    public class NumbersComparator implements Comparator {    // implements هنا فعلنا له

                    @Override                                             // لنحدد ماذا ستفعل عند استدعائها compare() للدالة Override هنا فعلنا
                    public int compare(Object o1, Object o2) {

                    if( o1 == null || o2 == null ) {     // سيتم إرجاع القيمة 0 o2 أو الكائن o1 مكان الكائن null إذا تم إدخال
                    return 0;
                    }

                    try {                                // num2 و num1 سيتم تخزينهم كأرقام عادية في المتغيرات null لا يساويان o2 و o1 إذا كان كلا الكائنان
                    double num1 = (double)o1;
                    double num2 = (double)o2;

                    if( num1 == num2 ) {             // سترجع 0 إلى مكان الإستدعاء num2 تساوي قيمة num1 في حال كانت قيمة
                    return 0;
                    }
                    else if( num1 > num2 ) {         // سترجع 1 إلى مكان الإستدعاء num2 أكبر من قيمة num1 في حال كانت قيمة
                    return 1;
                    }
                    else {                           // -1 هي الأكبر و عندها سيتم إرجاع num2 الإحتمال الأخير أن تكون قيمة
                    return -1;
                    }
                    }
                    catch(Exception e) {                 // إلى أرقام سيتم إرجاع 0 إلى مكان الإستدعاء o2 و o1 في حال كان لا يمكن تحويل قيمة كل من
                    return 0;
                    }

                    }

                    }
                  

Main.java
                    public class Main {

                    public static void main(String[] args) {

                    // منه compare() حتى نستطيع استخدام الدالة NumbersComparator هنا قمنا بإنشاء كائن من الكلاس
                    NumbersComparator nc = new NumbersComparator();

                    // هنا قمنا بقارنة رقمين مع بعضها في كل مرة مع عرض نتيجة المقارنة
                    System.out.println( nc.compare(20, 10) );
                    System.out.println( nc.compare(10, 20) );
                    System.out.println( nc.compare(20, 20) );

                    // تقارن الأرقام فقط compare() هنا سيتم عرض 0 في الحالتين لأننا جعلنا الدالة
                    System.out.println( nc.compare("java", "c++") );
                    System.out.println( nc.compare(null, 0) );

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    1
                    -1
                    0
                    0
                    0
                  
__________&&&______;&&&___________;&&&&________;

 الإنترفيس Iterator في جافا

مقدمة الإنترفيس Iterator في جافا

الإنترفيس Collection يرث من الإنترفيس Iterator. لذلك تجد كل كلاس تابع للإطار Collection يرث دالة إسمها iterator(), ترجع كائن نوعه Iterator يحتوي على جميع عناصر الكائن الذي قام باستدعائها.

إذاً الإنترفيس Iterator يستخدم لتخزين عناصر متتالية موجودة في أي كائن دفعة واحدة.
بعدها يمكن إرجاع هذه العناصر واحداً تلو الآخر.


طريقة استخدام الإنترفيس Iterator في جافا

هناك ثلاث مراحل أساسية عند التعامل مع الإنترفيس Iterator:

  1. جلب عناصر أي كائن تريد بواسطة الدالة iterator() و تخزينهم مباشرةً في كائن من الإنترفيس Iterator.

  2. إنشاء حلقة تمر على جميع العناصر الموجودة في كائن الـ Iterator بواسطة الدالة hasNext().

  3. الحصول على عنصر واحد من العناصر الموجودة في كائن الـ Iterator بواسطة الدالة next().


لا تنسى استخدام الإنترفيس Iterator بدل الإنترفيس Enumeration.

نلفت الإنتباه أيضاً أنه تم تطوير إنترفيس جديد إسمه ListIterator, يرث من الإنترفيس Iterator, و يملك دوال إضافية للتعامل مع العناصر المخزنة.

دوال الإنترفيس Iterator في جافا

الجدول التالي يحتوي على دوال الإنترفيس Iterator.

الدالة مع تعريفها
public boolean hasNext() ترجع true في حال كان كائن الـ Iterator لا يزال يحتوي على عناصر.
public Object next() ترجع العنصر التالي الموجود في كائن الـ Iterator, ترجعه كـ Object.
public Object remove() تحذف العنصر الحالي الموجود في كائن الـ Iterator و الذي أرجعته الدالة next() قبل استدعائها.
ترجع الإستثناء IllegalStateException في حال تم استدعائها بدون استدعاء الدالة next() قبلها.
مثال شامل

في المثال التالي قمنا بإنشاء كائن من الكلاس ArrayList إسمه al, ثم أدخلنا فيه خمسة عناصر.
بعدها وضعنا جميع عناصر الكائن al في كائن نوعه Iterator إسمه i.
في الأخير قمنا بإنشاء حلقة تعرض لنا جميع عناصر الكائن i.

Main.java
                    import java.util.ArrayList;         // ArrayList هنا قمنا باستدعاء الكلاس
                    import java.util.Iterator;          // Iterator هنا قمنا باستدعاء الإنترفيس

                    public class Main {

                    public static void main(String[] args) {

                    ArrayList al = new ArrayList();         // al إسمه ArrayList هنا قمنا بإنشاء كائن من الكلاس

                    al.add("A");                            // al هنا قمنا بإضافة 5 عناصر في الكائن
                    al.add("B");
                    al.add("C");
                    al.add("D");
                    al.add("E");

                    Iterator i = al.iterator();             // al وضعنا فيه جميع عناصر الكائن i إسمه Iterator هنا قمنا بإنشاء كائن نوعه

                    while(i.hasNext()) {                    // و تعرض كل عنصر تمر عليه i هنا أنشأنا حلقة تمر على جميع عناصر الكائن
                    System.out.println(i.next());
                    }

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    A
                    B
                    C
                    D
                    E
                  
__________&&&______;&&&___________;&&&&________; __________&&&______;&&&___________;&&&&________;

 الإنترفيس ListIterator في جافا

مقدمة الإنترفيس ListIterator في جافا

الإنترفيس ListIterator يرث من الإنترفيس Iterator, و يملك دوال إضافية للتعامل مع العناصر المخزنة.

إذاً يستخدم أيضاً لتخزين عناصر متتالية موجودة في أي كائن دفعة واحدة.
بعدها يمكن إرجاع هذه العناصر واحداً تلو الآخر.

الدوال التي يملكها تمكنك من المرور على العناصر الموجودة فيه من الأول إلى الأخير أو العكس.


طريقة استخدام الإنترفيس ListIterator في جافا

هناك ثلاث مراحل أساسية عند التعامل مع الإنترفيس ListIterator:

  1. جلب عناصر أي كائن تريد بواسطة الدالة ListIterator() و تخزينهم مباشرةً في كائن من الإنترفيس ListIterator.

  2. إنشاء حلقة تمر على جميع العناصر الموجودة في كائن الـ ListIterator بواسطة الدالة hasNext() أو hasPrevious().

  3. الحصول على عنصر واحد من العناصر الموجودة في كائن الـ ListIterator بواسطة الدالة next() أو previous().

دوال الإنترفيس ListIterator في جافا

الجدول التالي يحتوي على دوال الإنترفيس ListIterator.

الدالة مع تعريفها
public void add(Object obj) تضيف الكائن الذي نمرره لها كـ Argument في الكائن الذي قام باستدعائها.
ملاحظة: إذا قمت باستدعاء الدالة next() قبل استدعائها, عندها سيتم إضافة الكائن obj بعد أخر كائن أرجعته الدالة next().
public boolean hasNext() ترجع true في حال كان كائن الـ ListIterator يملك عنصر أو أكثر بعد العنصر الحالي.
public boolean hasPrevious() ترجع true في حال كان كائن الـ ListIterator يملك عنصر أو أكثر قبل العنصر الحالي.
public Object next() ترجع العنصر التالي الموجود في كائن الـ ListIterator, ترجعه كـ Object.
public int nextIndex() ترجع Index العنصر التالي الموجود في كائن الـ ListIterator.
في حال تم المرور على جميع عناصر كائن الـ ListIterator ترجع Index آخر عنصر تم الوصول إليه.
public Object previous() ترجع العنصر السابق الموجود في كائن الـ ListIterator, ترجعه كـ Object.
public int previousIndex() ترجع Index العنصر السابق الموجود في كائن الـ ListIterator.
ترجع 1- في حال لم يتم الوصول إلى أي عنصر قبل استدعائها.
public Object remove() تحذف العنصر الحالي, أي آخر عنصر تم الوصول إليه قبل استدعائها.
public void set(Object obj) تضع قيمة الكائن الذي نمرره لها كـ Argument كقيمة جديدة للعنصر الحالي, أي مكان آخر عنصر تم الوصول إليه.
أمثلة شاملة
المثال الأول

في المثال التالي قمنا بإنشاء كائن من الكلاس ArrayList إسمه al, ثم أدخلنا فيه خمسة عناصر.
بعدها وضعنا جميع عناصر الكائن al في كائن نوعه ListIterator إسمه li.
في الأخير قمنا بإنشاء حلقة تعرض جميع عناصر الكائن li من العنصر الأول إلى العنصر الأخير.

قمنا باستخدام الدوال hasNext() و next() في الحلقة حتى نستطيع جلب العنصر التالي في الكائن li في كل دورة.

Main.java
                    import java.util.ArrayList;           // ArrayList هنا قمنا باستدعاء الكلاس
                    import java.util.ListIterator;        // ListIterator هنا قمنا باستدعاء الإنترفيس

                    public class Main {

                    public static void main(String[] args) {

                    // al إسمه ArrayList هنا قمنا بإنشاء كائن من الكلاس
                    ArrayList al = new ArrayList();

                    // al هنا قمنا بإضافة 5 عناصر في الكائن
                    al.add("A");
                    al.add("B");
                    al.add("C");
                    al.add("D");
                    al.add("E");

                    // al وضعنا فيه جميع عناصر الكائن li إسمه ListIterator هنا قمنا بإنشاء كائن نوعه
                    ListIterator li = al.listIterator();

                    // من العنصر الأول إلى العنصر الأخير و تعرض كل عنصر تمر عليه i هنا أنشأنا حلقة تمر على جميع عناصر الكائن
                    while(li.hasNext()) {
                    System.out.println(li.next());
                    }

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    A
                    B
                    C
                    D
                    E
                  


المثال الثاني

في هذا المثال  قمنا بإنشاء كائن من الكلاس ArrayList إسمه al, ثم أدخلنا فيه خمسة عناصر.
بعدها وضعنا جميع عناصر الكائن al في كائن نوعه ListIterator إسمه li.
في الأخير قمنا بإنشاء حلقة تعرض جميع عناصر الكائن li من العنصر الأخير إلى العنصر الأول.

قمنا باستخدام الدوال hasPrevious() و previous() في الحلقة حتى نستطيع جلب العنصر السابق في الكائن li في كل دورة.

Main.java
                    import java.util.ArrayList;             // ArrayList هنا قمنا باستدعاء الكلاس
                    import java.util.ListIterator;          // ListIterator هنا قمنا باستدعاء الإنترفيس

                    public class Main {

                    public static void main(String[] args) {

                    // al إسمه ArrayList هنا قمنا بإنشاء كائن من الكلاس
                    ArrayList al = new ArrayList();

                    // al هنا قمنا بإضافة 5 عناصر في الكائن
                    al.add("A");
                    al.add("B");
                    al.add("C");
                    al.add("D");
                    al.add("E");

                    // و حددنا عدد عناصره حتى نستطيع البداية من العناصر الأخير فيه al وضعنا فيه جميع عناصر الكائن li إسمه ListIterator هنا قمنا بإنشاء كائن نوعه
                    ListIterator li = al.listIterator(al.size());

                    // من العنصر الأخير إلى العنصر الأول و تعرض كل عنصر تمر عليه i هنا أنشأنا حلقة تمر على جميع عناصر الكائن
                    while(li.hasPrevious()) {
                    System.out.println(li.previous());
                    }

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    E
                    D
                    C
                    B
                    A
                  


المثال الثالث

في هذا المثال  قمنا بإنشاء كائن من الكلاس ArrayList إسمه al, ثم أدخلنا فيه خمسة عناصر.
بعدها وضعنا جميع عناصر الكائن al في كائن نوعه ListIterator إسمه li.
في الأخير قمنا بإنشاء حلقتين: الأولى تعرض جميع عناصر الكائن li من العنصر الأول إلى العنصر الأخير, و الثانية تعرضهم بالعكس.

Main.java
                    import java.util.ArrayList;             // ArrayList هنا قمنا باستدعاء الكلاس
                    import java.util.ListIterator;          // ListIterator هنا قمنا باستدعاء الإنترفيس

                    public class Main {

                    public static void main(String[] args) {

                    // al إسمه ArrayList هنا قمنا بإنشاء كائن من الكلاس
                    ArrayList al = new ArrayList();

                    // al هنا قمنا بإضافة 5 عناصر في الكائن
                    al.add("A");
                    al.add("B");
                    al.add("C");
                    al.add("D");
                    al.add("E");

                    // al وضعنا فيه جميع عناصر الكائن li إسمه ListIterator هنا قمنا بإنشاء كائن نوعه
                    ListIterator li = al.listIterator();

                    System.out.println("Ascending sort order:");

                    // من العنصر الأول إلى العنصر الأخير و تعرض كل عنصر تمر عليه i هنا أنشأنا حلقة تمر على جميع عناصر الكائن
                    while(li.hasNext()) {
                    System.out.print(li.next()+" ");
                    }

                    System.out.println("\n");

                    System.out.println("Descending sort order:");

                    // من العنصر الأخير إلى العنصر الأول و تعرض كل عنصر تمر عليه i هنا أنشأنا حلقة تمر على جميع عناصر الكائن
                    while(li.hasPrevious()) {
                    System.out.print(li.previous()+" ");
                    }

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    Ascending sort order:
                    A B C D E

                    Descending sort order:
                    E D C B A
                  
__________&&&______;&&&___________;&&&&________;

الكلاس ArrayList في جافا

مقدمة

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

أهم ميزة في المصفوفات التي نوعها ArrayList هي أن عدد العناصر فيها غير ثابت, حيث أنه يزيد عند إضافة عنصر جديد فيها و ينقص عند حذف عنصر منها بشكل تلقائي, و هذه الميزة غير موجودة في المصفوفات العادية.

كما أنك تستطيع الوصول للعناصر الموجودة فيها عن طريق أرقام الـ Index التي تعطى بالترتيب لكل عنصر يضاف فيها.


بناؤه
                  public class ArrayList<E>
                  extends AbstractList<E>
                  implements List<E>, RandomAccess, Cloneable, Serializable 
                

إذاً الكلاس ArrayList يرث من الكلاس AbstractList, و يطبق الإنترفيسات List - Serializable - Cloneable - RandomAccess.

كونستركتورات الكلاس ArrayList

الجدول التالي يحتوي على جميع الكونستركتورات الموجودين في الكلاس ArrayList.

الكونستركتور مع تعريفه
public ArrayList() هذا الكونستركتور الإفتراضي في الكلاس ArrayList, يستخدم لإنشاء كائن نوعه ArrayList فارغ.
public ArrayList(int initialCapacity) يستخدم هذا الكونستركتور لتحديد حجم كائن الـ ArrayList الأولي.
الرقم الذي نضعه كـ Argument في هذا الكونستركتور يحدد عدد عناصر كائن الـ ArrayList الذي يمكنه احتوائهم على الأقل.
public ArrayList(Collection c) يستخدم هذا الكونستركتور لإنشاء كائن نوعه ArrayList يحتوي على عناصر كائن الـ Collection الذي نمرره له كـ Argument.

دوال الكلاس ArrayList

الجدول التالي يحتوي على جميع دوال الكلاس ArrayList.

الدالة مع تعريفها
public void add(int index, Object obj) تضيف عنصر جديد في مكان محدد في كائن الـ ArrayList.
  • obj هو الكائن الذي سيضاف.

  • index هو رقم الـ index الذي سيضاف فيه الكائن obj.

ترمي الإستثناء IndexOutOfBoundsException في حال كان الـ index المحدد فيها أصغر من 0 أو أكبر من عدد العناصر الموجودة.
public boolean add(Object o) تضيف عنصر جديد في آخر كائن الـ ArrayList.
ترجع true إذا تمت الإضافة بنجاح.
public boolean addAll(Collection c) تضيف جميع عناصر الكائن c في آخر كائن الـ ArrayList.
ترجع true إذا تمت الإضافة بنجاح.
ترمي الإستثناء NullPointerException في حال كان الكائن c فارغاً.
public boolean addAll(int index, Collection c) تضيف جميع عناصر الكائن c في مكان محدد في كائن الـ ArrayList.
ترجع true إذا تمت الإضافة بنجاح.
  • c هو مجموعة الكائنات التي ستضاف.

  • index هو رقم الـ index الذي سيضاف فيه الكائن c.

ترمي الإستثناء NullPointerException في حال كان الكائن c فارغاً.
public void clear() تمسح جميع العناصر الموجودة في كائن الـ ArrayList.
public Object clone() ترجع نسخة من كائن الـ ArrayList.
public boolean contains(Object o) ترجع true في حال كان كائن الـ ArrayList يملك الكائن الذي نضعه لها كـ Argument.
public void ensureCapacity(int minCapacity) تحدد عدد العناصر الأقل الذي يجب أن يحجز لكائن الـ ArrayList في الذاكرة.
إذا كان العدد الموضوع فيها أكبر من عدد العناصر المحجوز لكائن الـ ArrayList, عندها يتم تكبير حجمه.
إذا كان العدد الموضوع فيها أصغر من عدد العناصر الموجودة في كائن الـ ArrayList, لن تفعل أي شيء.
public Object get(int index) ترجع العنصر الموجود على الـ index الذي نمرره لها كـ Argument.
ترمي الإستثناء IndexOutOfBoundsException في حال كان الـ index المحدد فيها أصغر من 0 أو أكبر من عدد العناصر الموجودة.
public int indexOf(Object o) تبحث في كائن الـ ArrayList عن أي قيمة نمررها لها كـ Argument.
ترجع رقم أول Index يحتوي على القيمة المطلوبة في حال وجود نفس القيمة في أكثر من عنصر.
ترجع 1- في حال عدم إيجاد القيمة المطلوبة.
public int lastIndexOf(Object o) تبحث في كائن الـ ArrayList عن أي قيمة نمررها لها كـ Argument.
ترجع رقم آخر Index يحتوي على القيمة المطلوبة في حال وجود نفس القيمة في أكثر من عنصر.
ترجع 1- في حال عدم إيجاد القيمة المطلوبة.
public Object remove(int index) تحذف عنصر محدد من كائن الـ ArrayList.
ترمي الإستثناء IndexOutOfBoundsException في حال كان الـ index المحدد فيها أصغر من 0 أو أكبر من عدد العناصر الموجودة.
protected void removeRange(int fromIndex, int toIndex) تحذف جميع عناصر كائن الـ ArrayList الموجودة من fromIndex إلى toIndex.
public Object set(int index, Object element) تبدل عنصر محدد في كائن الـ ArrayList بعنصر جديد, و ترجعه أيضاً.
ترمي الإستثناء IndexOutOfBoundsException في حال كان الـ index المحدد فيها أصغر من 0 أو أكبر من عدد العناصر الموجودة.
public int size() ترجع عدد العناصر الموجودة في كائن الـ ArrayList.
public Object[] toArray() ترجع مصفوفة نوعها Object تحتوي على جميع العناصر الموجودة في كائن الـ ArrayList.
public void trimToSize() تصغر حجم كائن الـ ArrayList في الذاكرة, حيث أنها تحذف جميع الأماكن المحجوزة له في الذاكرة و التي لم يضطر إلى استخدامها.
أمثلة شاملة

في كل مثال موضوع استخدامنا كونستركتور مختلف و دوال جديدة.



المثال الأول

في المثال التالي قمنا بتعريف كائن نوعه ArrayList أدخلنا فيه 5 عناصر ثم حذفنا منه عنصرين.

استخدامنا الدوال التالية: add() - remove() - size().

Main.java
                    import java.util.ArrayList;   // ArrayList هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // al إسمه ArrayList هنا قمنا بإنشاء كائن من الكلاس
                    ArrayList al = new ArrayList();

                    // و عرض عددهم al هنا قمنا بعرض عناصر الكائن
                    System.out.println("All elements:       " + al);
                    System.out.println("Number of elements: " + al.size() + "\n");

                    // al هنا قمنا بإضافة 5 عناصر في الكائن
                    al.add("A");
                    al.add("B");
                    al.add("C");
                    al.add("D");
                    al.add("E");

                    // و عرض عددهم al هنا قمنا بعرض عناصر الكائن
                    System.out.println("All elements:       " + al);
                    System.out.println("Number of elements: " + al.size() + "\n");

                    // رقم 1 index و العنصر الموجود على الـ 'B' هنا قمنا بحذف العنصر الذي يملك القيمة
                    al.remove("B");
                    al.remove(1);

                    // و عرض عددهم al هنا قمنا بعرض عناصر الكائن
                    System.out.println("All elements:       " + al);
                    System.out.println("Number of elements: " + al.size() + "\n");

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    All elements:       []
                    Number of elements: 0

                    All elements:       [A, B, C, D, E]
                    Number of elements: 5

                    All elements:       [A, D, E]
                    Number of elements: 3 
                  


المثال الثاني

في المثال التالي قمنا بإضافة كائن نوعه ArrayListفي كائن آخر نوعه ArrayList.
لاحظ هنا أنه عند إضافة كائن بواسطة الدالة add(Collection c) فإن جميع عناصره توضع في عنصر واحد.

Main.java
                    import java.util.ArrayList;   // ArrayList هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // arr1 إسمه ArrayList هنا قمنا بإنشاء كائن من الكلاس
                    ArrayList arr1 = new ArrayList();

                    // arr1 هنا قمنا بإضافة 5 عناصر في الكائن
                    arr1.add("A");
                    arr1.add("B");
                    arr1.add("C");
                    arr1.add("D");
                    arr1.add("E");

                    // arr2 إسمه ArrayList هنا قمنا بإنشاء كائن آخر من الكلاس
                    ArrayList arr2 = new ArrayList();

                    // arr2 في أول عنصر في الكائن arr1 هنا قمنا بإضافة جميع عناصر الكائن
                    arr2.add(arr1);

                    // arr1 و الذي يمثل مصفوفة تحتوي على جميع عناصر الكائن arr2 هنا قمنا بطباعة العنصر الأول الموجود في الكائن
                    System.out.println("arr2 elements: " + arr2.get(0) + "\n");

                    // arr2 هنا قمنا بعرض عدد عناصر الكائن
                    System.out.println("Number of elements in arr2 : " + arr2.size());

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    arr2 elements: [A, B, C, D, E]

                    Number of elements in arr2 : 1 
                  


المثال الثالث

في المثال التالي قمنا بتمرير كائن نوعه ArrayListفي كونستركتور كائن آخر نوعه ArrayList.
لاحظ هنا أن جميع عناصر الكائن الأول ستوضع بنفس الترتيب في الكائن الثاني, و سيوضع كل كائن في عنصر أيضاً.

Main.java
                    import java.util.ArrayList;   // ArrayList هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // arr1 إسمه ArrayList هنا قمنا بإنشاء كائن من الكلاس
                    ArrayList arr1 = new ArrayList();

                    // arr1 هنا قمنا بإضافة 5 عناصر في الكائن
                    arr1.add("A");
                    arr1.add("B");
                    arr1.add("C");
                    arr1.add("D");
                    arr1.add("E");

                    // arr1 يحتوي على جميع عناصر الكائن arr2 إسمه ArrayList هنا قمنا بإنشاء كائن آخر من الكلاس
                    ArrayList arr2 = new ArrayList(arr1);

                    // arr2 هنا قمنا بإضافة عنصر جديد في الكائن
                    arr2.add("F");

                    // arr2 و arr1 هنا عرضنا جميع العناصر الموجودة في الكائنين
                    System.out.println("arr1 elements: " + arr1);
                    System.out.println("arr2 elements: " + arr2);

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    arr1 elements: [A, B, C, D, E]
                    arr2 elements: [A, B, C, D, E, F]
                  


المثال الرابع

في المثال التالي قمنا باستخدام الدوال التي تستخدم في البحث و التشييك.

استخدامنا الدوال التالية: add() - get() - size() - indexOf() - lastIndexOf() - contains().

Main.java
                    import java.util.ArrayList;   // ArrayList هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // al إسمه ArrayList هنا قمنا بإنشاء كائن من الكلاس
                    ArrayList al = new ArrayList();

                    // al هنا قمنا بإضافة 9 عناصر في الكائن
                    al.add("A");
                    al.add("B");
                    al.add("C");
                    al.add("D");
                    al.add("E");
                    al.add("A");
                    al.add("B");
                    al.add("C");
                    al.add("Z");

                    // al هنا عرضنا العنصر الأول في الكائن
                    System.out.println("First element: " + al.get(0));

                    // al هنا عرضنا العنصر الأخير في الكائن
                    System.out.println("Last element:  " + al.get(al.size()-1) + "\n");

                    // al هنا عرضنا خامس عنصر موجود في الكائن
                    System.out.println("Element at al[4]: " + al.get(4) + "\n");

                    // al موجودين في الكائن 'C' أول و آخر كائن index هنا عرضنا
                    System.out.println("First index of the object 'C': " + al.indexOf("C"));
                    System.out.println("Last index of the object 'C':  " + al.lastIndexOf("C") + "\n");

                    // F و D عن الكائنين al هنا بحثنا في عناصر الكائن
                    System.out.println("Does it contain a 'D' object? " + al.contains("D"));
                    System.out.println("Does it contain a 'F' object? " + al.contains("F"));

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    First element: A
                    Last element: Z

                    Element at al[4]: E

                    First index of the object 'C': 2
                    Last index of the object 'C': 7

                    Does it contain a 'D' object? true
                    Does it contain a 'F' object? false
                  


المثال الخامس

في المثال التالي قمنا بنسخ عناصر كائن الـ ArrayList بداخل مصفوفة جديدة نوعها Object بواسطة الدالة toArray().

Main.java
                    import java.util.ArrayList;   // ArrayList هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // al إسمه ArrayList هنا قمنا بإنشاء كائن من الكلاس
                    ArrayList al = new ArrayList();

                    // al هنا قمنا بإضافة 3 عناصر في الكائن
                    al.add("A");
                    al.add("B");
                    al.add("C");

                    // al عدد عناصرها يساوي عدد عناصر الكائن ,Object هنا قمنا بإنشاء مصفوفة نوعها
                    Object[] arr = new Object[al.size()];

                    // arr بنفس الترتيب في المصفوفة al هنا قمنا بنسخ عناصر الكائن
                    al.toArray(arr);

                    // arr هنا أنشأنا حلقة تعرض جميع العناصر الموجودة في الحلقة
                    for(int i=0; i<arr.length; i++) {
                    System.out.println("arr[" +i+ "] = " +arr[i]);
                    }

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    arr[0] = A
                    arr[1] = B
                    arr[2] = C
                  


المثال السادس

في المثال التالي قمنا بإنشاء نسخة ثانية من كائن الـ ArrayList في كائن جديد نوعه Object بواسطة الدالة clone(), بعدها قمنا بمسح كائن الـ ArrayList الأصلي.

إنتبه: النسخة التي أنشأناها هنا تعتبر مجرد صورة للأشياء الموجودة في كائن الـ ArrayList.

Main.java
                    import java.util.ArrayList;   // ArrayList هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // al إسمه ArrayList هنا قمنا بإنشاء كائن من الكلاس
                    ArrayList al = new ArrayList();

                    // al هنا قمنا بإضافة 3 عناصر في الكائن
                    al.add("A");
                    al.add("B");
                    al.add("C");

                    // o في الكائن al هنا قمنا بنسخ عناصر الكائن
                    Object o = al.clone();

                    // al هنا قمنا بمسح جميع عناصر الكائن
                    al.clear();

                    // o و al هنا قمنا بعرض عناصر كل من الكائنات
                    System.out.println("al = " +al);
                    System.out.println("o  = " +o);

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    al = []
                    o  = [A, B, C]
                  


المثال السابع

في المثال التالي قمنا بتحديد نوع الكائنات التي يمكن إدخالها في كائنات الـ ArrayList من خلال تطبيق مبدأ الـ Generics.

ملاحظة: سنشرح الـ Generics في درس خاص و هذا مجرد مثال بسيط.

Main.java
                    import java.util.ArrayList;   // ArrayList هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // يمكنه تخزين كائنات من أي نوع كان arr1 إسمه ArrayList هنا قمنا بإنشاء كائن من الكلاس
                    ArrayList arr1 = new ArrayList();

                    // فقط String يمكنه تخزين كائنات من النوع arr2 إسمه ArrayList هنا قمنا بإنشاء كائن من الكلاس
                    ArrayList<String> arr2 = new ArrayList<>();

                      // فقط Integer يمكنه تخزين كائنات من النوع arr3 إسمه ArrayList هنا قمنا بإنشاء كائن من الكلاس
                      ArrayList<Integer> arr3 = new ArrayList<>();


                        // arr1 هنا قمنا بإضافة 5 عناصر لها أنواع مختلفة في الكائن
                        arr1.add(null);
                        arr1.add(true);
                        arr1.add(1234);
                        arr1.add("java");
                        arr1.add('A');

                        // arr2 في الكائن String هنا قمنا بإضافة 3 عناصر نوعها
                        arr2.add("A");
                        arr2.add("B");
                        arr2.add("C");

                        // arr3 في الكائن int هنا قمنا بإضافة 3 عناصر نوعها
                        arr3.add(1);
                        arr3.add(2);
                        arr3.add(3);


                        // arr1 هنا قمنا بعرض عناصر الكائن
                        System.out.println("arr1: " +arr1);

                        // arr2 هنا قمنا بعرض عناصر الكائن
                        System.out.println("arr2: " +arr2);

                        // arr3 هنا قمنا بعرض عناصر الكائن
                        System.out.println("arr3: " +arr3);

                        }

                        }
                      

سنحصل على النتيجة التالية عند التشغيل.

                    arr1: [null, true, 1234, java, A]
                    arr2: [A, B, C]
                    arr3: [1, 2, 3]
                  
__________&&&______;&&&___________;&&&&________;

 الكلاس LinkedList في جافا

مقدمة

الكلاس LinkedList يستخدم لإنشاء مصفوفات متطورة مقارنةً مع المصفوفات العادية Arrays, حيث يوفر لك مجموعة من الدوال التي تمكنك من البحث فيها, التشييك على عناصرها, إضافة عناصر جديدة, حذف عناصر منها, و معالجة أكثر من عنصر فيها في نفس الوقت إلخ..

أهم ميزة في المصفوفات التي نوعها LinkedList هي أن عدد العناصر فيها غير ثابت, حيث أنه يزيد عند إضافة عنصر جديد فيها و ينقص عند حذف عنصر منها بشكل تلقائي, و هذه الميزة غير موجودة في المصفوفات العادية.

كما أنك تستطيع الوصول للعناصر الموجودة فيها عن طريق أرقام الـ Index التي تعطى بالترتيب لكل عنصر يضاف فيها.


بناؤه
                  public class LinkedList<E>
                  extends AbstractSequentialList<E>
                  implements List<E>, Deque<E>, Cloneable, Serializable
                

إذاً الكلاس LinkedList يرث من الكلاس AbstractSequentialList, و يطبق الإنترفيسات List - Deque - Cloneable - Serializable.



الفرق بين الكلاس LinkedList و الكلاس ArrayList

الكلاس LinkedList يشبه كثيراً الكلاس ArrayList, الفرق بينهما هو التالي:

  • مترجم لغة جافا يعامل الكلاس LinkedList بشكل أسرع من الكلاس ArrayList.

  • الكلاس LinkedList يملك دوال للحذف و الإضافة ليست موجودة في الكلاس ArrayList.

  • الكلاس LinkedList يحتل مساحة أكبر في الذاكرة مقارنةً مع المساحة التي يحتلها الكلاس ArrayList.

كونستركتورات الكلاس LinkedList

الجدول التالي يحتوي على جميع الكونستركتورات الموجودين في الكلاس LinkedList.

الكونستركتور مع تعريفه
public LinkedList() هذا الكونستركتور الإفتراضي في الكلاس LinkedList, يستخدم لإنشاء كائن نوعه LinkedList فارغ.
public LinkedList(Collection c) يستخدم هذا الكونستركتور لإنشاء كائن نوعه LinkedList يحتوي على عناصر كائن الـ Collection الذي نمرره له كـ Argument.

دوال الكلاس LinkedList

الجدول التالي يحتوي على جميع دوال الكلاس LinkedList.

الدالة مع تعريفها
public void add(int index, Object obj) تضيف عنصر جديد في مكان محدد في كائن الـ LinkedList.
  • obj هو الكائن الذي سيضاف.

  • index هو رقم الـ index الذي سيضاف فيه الكائن obj.

ترمي الإستثناء IndexOutOfBoundsException في حال كان الـ index المحدد فيها أصغر من 0 أو أكبر من عدد العناصر الموجودة.
public boolean add(Object o) تضيف عنصر جديد في آخر كائن الـ LinkedList.
ترجع true إذا تمت الإضافة بنجاح.
public boolean addAll(Collection c) تضيف جميع عناصر الكائن c في آخر كائن الـ LinkedList.
ترجع true إذا تمت الإضافة بنجاح.
ترمي الإستثناء NullPointerException في حال كان الكائن c فارغاً.
public boolean addAll(int index, Collection c) تضيف جميع عناصر الكائن c في مكان محدد في كائن الـ LinkedList.
ترجع true إذا تمت الإضافة بنجاح.
  • c هو مجموعة الكائنات التي ستضاف.

  • index هو رقم الـ index الذي سيضاف فيه الكائن c.

ترمي الإستثناء NullPointerException في حال كان الكائن c فارغاً.
public void addFirst(Object o) تضيف عنصر في أول كائن الـ LinkedList.
public void addLast(Object o) تضيف عنصر في آخر كائن الـ LinkedList.
public void clear() تمسح جميع العناصر الموجودة في كائن الـ LinkedList.
public Object clone() ترجع نسخة من كائن الـ LinkedList.
public boolean contains(Object o) ترجع true في حال كان كائن الـ LinkedList يملك الكائن الذي نضعه لها كـ Argument.
public Object get(int index) ترجع العنصر الموجود على الـ index الذي نمرره لها كـ Argument.
ترمي الإستثناء IndexOutOfBoundsException في حال كان الـ index المحدد فيها أصغر من 0 أو أكبر من عدد العناصر الموجودة.
public Object getFirst() ترجع أول عنصر موجود في كائن الـ LinkedList.
ترمي الإستثناء NoSuchElementException في حال كان كائن الـ LinkedList فارغاً.
public Object getLast() ترجع آخر عنصر موجود في كائن الـ LinkedList.
ترمي الإستثناء NoSuchElementException في حال كان كائن الـ LinkedList فارغاً.
public int indexOf(Object o) تبحث في كائن الـ LinkedList عن أي قيمة نمررها لها كـ Argument.
ترجع رقم أول Index يحتوي على القيمة المطلوبة في حال وجود نفس القيمة في أكثر من عنصر.
ترجع 1- في حال عدم إيجاد القيمة المطلوبة.
public int lastIndexOf(Object o) تبحث في كائن الـ LinkedList عن أي قيمة نمررها لها كـ Argument.
ترجع رقم آخر Index يحتوي على القيمة المطلوبة في حال وجود نفس القيمة في أكثر من عنصر.
ترجع 1- في حال عدم إيجاد القيمة المطلوبة.
public ListIterator listIterator(int index) ترجع كائن نوعه ListIterator يحتوي على جميع عناصر كائن الـ LinkedList.
public Object remove() تحذف أول عنصر موجود في كائن الـ LinkedList و ترجعه.
ترمي الإستثناء NoSuchElementException في حال كان كائن الـ LinkedList فارغأً.
public Object remove(int index) تحذف عنصر محدد من كائن الـ LinkedList و ترجعه.
ترمي الإستثناء IndexOutOfBoundsException في حال كان الـ index المحدد فيها أصغر من 0 أو أكبر من عدد العناصر الموجودة.
public boolean remove(Object o) تحذف عنصر محدد من كائن الـ LinkedList و ترجعه.
ترجع true إذا تم حذف الكائن بنجاح, غير ذلك ترجع false.
public Object removeFirst() تحذف أول عنصر موجود كائن الـ LinkedList و ترجعه.
ترمي الإستثناء NoSuchElementException في حال كان كائن الـ LinkedList فارغأً.
public Object removeLast() تحذف آخر عنصر موجود كائن الـ LinkedList و ترجعه.
ترمي الإستثناء NoSuchElementException في حال كان كائن الـ LinkedList فارغأً.
public Object set(int index, Object element) تبدل عنصر محدد في كائن الـ LinkedList بعنصر جديد, و ترجعه أيضاً.
ترمي الإستثناء IndexOutOfBoundsException في حال كان الـ index المحدد فيها أصغر من 0 أو أكبر من عدد العناصر الموجودة.
public int size() ترجع عدد العناصر الموجودة في كائن الـ LinkedList.
public Object[] toArray() ترجع مصفوفة نوعها Object تحتوي على جميع العناصر الموجودة في كائن الـ LinkedList.
public Object[] toArray(Object[] array) ترجع مصفوفة نوعها Object تحتوي على جميع العناصر الموجودة في كائن الـ LinkedList في حال كانوا من نفس نوع المصفوفة array التي نمررها لها كـ Argument.
إذاً المصفوفة array تجعل مترجم جافا يحدد نوع المصفوفة المراد إرجاعها, أي يستخدمها المترجم لفحص نوع عناصر كائن الـ LinkedList.
في حال وجد نوع المصفوفة array مطابق لنوع العناصر الموجودة في كائن الـ LinkedList سيقوم بإرجاع هذه العناصر في مصفوفة جديدة و لن يظهر أي خطأ.
في حال وجد نوع المصفوفة array يختلف عن نوع العناصر الموجودة في كائن الـ LinkedList سيظهر لك الخطأ RuntimeException قبل التشغيل.
أمثلة شاملة

في كل مثال موضوع استخدامنا كونستركتور مختلف و دوال جديدة.



المثال الأول

في المثال التالي قمنا بتعريف كائن نوعه LinkedList أدخلنا فيه 6 عناصر ثم حذفنا منه عنصرين.

استخدامنا الدوال التالية: add() - addFirst() - addLast() - remove() - size().

Main.java
                    import java.util.LinkedList;    // LinkedList هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // arr إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
                    LinkedList arr = new LinkedList();

                    // و عرض عددهم arr هنا قمنا بعرض عناصر الكائن
                    System.out.println("All elements:       " + arr);
                    System.out.println("Number of elements: " + arr.size() + "\n");

                    arr.add("B");         // [B]                ==> arr في العنصر الكائن B هنا قمنا بإضافة الكائن
                    arr.add("C");         // [B, C]             ==> arr في العنصر الكائن C هنا قمنا بإضافة الكائن
                    arr.add("E");         // [B, C, E]          ==> arr في العنصر الكائن E هنا قمنا بإضافة الكائن
                    arr.add(2, "D");      // [B, C, D, E]       ==> arr في العنصر الثالث في الكائن D هنا قمنا بإضافة الكائن
                    arr.addFirst("A");    // [A, B, C, D, E]    ==> arr في أول عنصر في الكائن A هنا قمنا بإضافة الكائن
                    arr.addLast("F");     // [A, B, C, D, E, F] ==> arr في آخر الكائن F هنا قمنا بإضافة الكائن

                    // و عرض عددهم arr هنا قمنا بعرض عناصر الكائن
                    System.out.println("All elements:       " + arr);
                    System.out.println("Number of elements: " + arr.size() + "\n");

                    arr.remove();         // [B, C, D, E, F] ==> arr هنا قمنا بحذف أول عنصر موجود في الكائن
                    arr.remove(2);        // [B, C, E, F]    ==> arr هنا قمنا بحذف العنصر الثالث في الكائن
                    arr.remove("B");      // [C, E, F]       ==> arr في الكائن B هنا قمنا بحذف العنصر الذي يملك الكائن

                    // و عرض عددهم arr هنا قمنا بعرض عناصر الكائن
                    System.out.println("All elements:       " + arr);
                    System.out.println("Number of elements: " + arr.size() + "\n");

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    All elements:       []
                    Number of elements: 0

                    All elements:       [A, B, C, D, E]
                    Number of elements: 5

                    All elements:       [A, D, E]
                    Number of elements: 3 
                  


المثال الثاني

في المثال التالي قمنا بإضافة كائن نوعه LinkedListفي كائن آخر نوعه LinkedList.
لاحظ هنا أنه عند إضافة كائن بواسطة الدالة add(Collection c) فإن جميع عناصره توضع في عنصر واحد.

Main.java
                    import java.util.LinkedList;    // LinkedList هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // arr1 إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
                    LinkedList arr1 = new LinkedList();

                    // arr1 هنا قمنا بإضافة 5 عناصر في الكائن
                    arr1.add("A");
                    arr1.add("B");
                    arr1.add("C");
                    arr1.add("D");
                    arr1.add("E");

                    // arr2 إسمه LinkedList هنا قمنا بإنشاء كائن آخر من الكلاس
                    LinkedList arr2 = new LinkedList();

                    // arr2 في أول عنصر في الكائن arr1 هنا قمنا بإضافة جميع عناصر الكائن
                    arr2.add(arr1);

                    // arr1 و الذي يمثل مصفوفة تحتوي على جميع عناصر الكائن arr2 هنا قمنا بطباعة العنصر الأول الموجود في الكائن
                    System.out.println("arr2 elements: " + arr2.get(0) + "\n");

                    // arr2 هنا قمنا بعرض عدد عناصر الكائن
                    System.out.println("Number of elements in arr2 : " + arr2.size());

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    arr2 elements: [A, B, C, D, E]

                    Number of elements in arr2 : 1 
                  


المثال الثالث

في المثال التالي قمنا بتمرير كائن نوعه LinkedListفي كونستركتور كائن آخر نوعه LinkedList.
لاحظ هنا أن جميع عناصر الكائن الأول ستوضع بنفس الترتيب في الكائن الثاني, و سيوضع كل كائن في عنصر أيضاً.

Main.java
                    import java.util.LinkedList;    // LinkedList هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // arr1 إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
                    LinkedList arr1 = new LinkedList();

                    // arr1 هنا قمنا بإضافة 5 عناصر في الكائن
                    arr1.add("A");
                    arr1.add("B");
                    arr1.add("C");
                    arr1.add("D");
                    arr1.add("E");

                    // arr1 يحتوي على جميع عناصر الكائن arr2 إسمه LinkedList هنا قمنا بإنشاء كائن آخر من الكلاس
                    LinkedList arr2 = new LinkedList(arr1);

                    // arr2 هنا قمنا بإضافة عنصر جديد في الكائن
                    arr2.add("F");

                    // arr2 و arr1 هنا عرضنا جميع العناصر الموجودة في الكائنين
                    System.out.println("arr1 elements: " + arr1);
                    System.out.println("arr2 elements: " + arr2);

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    arr1 elements: [A, B, C, D, E]
                    arr2 elements: [A, B, C, D, E, F] 
                  


المثال الرابع

في المثال التالي قمنا باستخدام الدوال التي تستخدم في البحث و التشييك.

استخدامنا الدوال التالية: add() - get() - getFirst() - getLast() - size() - indexOf() - lastIndexOf() - contains().

Main.java
                    import java.util.LinkedList;    // LinkedList هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // arr إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
                    LinkedList arr = new LinkedList();

                    // arr هنا قمنا بإضافة 9 عناصر في الكائن
                    arr.add("A");
                    arr.add("B");
                    arr.add("C");
                    arr.add("D");
                    arr.add("E");
                    arr.add("A");
                    arr.add("B");
                    arr.add("C");
                    arr.add("Z");

                    // arr هنا عرضنا العنصر الأول في الكائن
                    System.out.println("First element: " + arr.getFirst());

                    // arr هنا عرضنا العنصر الأخير في الكائن
                    System.out.println("Last element:  " + arr.getLast() + "\n");

                    // arr هنا عرضنا خامس عنصر موجود في الكائن
                    System.out.println("Element at al[4]: " + arr.get(4) + "\n");

                    // arr موجودين في الكائن 'C' أول و آخر كائن index هنا عرضنا
                    System.out.println("First index of the object 'C': " + arr.indexOf("C"));
                    System.out.println("Last index of the object 'C':  " + arr.lastIndexOf("C") + "\n");

                    // F و D عن الكائنين arr هنا بحثنا في عناصر الكائن
                    System.out.println("Does it contain a 'D' object? " + arr.contains("D"));
                    System.out.println("Does it contain a 'F' object? " + arr.contains("F"));

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    First element: A
                    Last element: Z

                    Element at al[4]: E

                    First index of the object 'C': 2
                    Last index of the object 'C': 7

                    Does it contain a 'D' object? true
                    Does it contain a 'F' object? false 
                  


المثال الخامس

في المثال التالي قمنا بنسخ عناصر كائن الـ LinkedList بداخل مصفوفة جديدة نوعها Object بواسطة الدالة toArray().

Main.java
                    import java.util.LinkedList;    // LinkedList هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // arr1 إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
                    LinkedList arr1 = new LinkedList();

                    // arr1 هنا قمنا بإضافة 3 عناصر في الكائن
                    arr1.add("A");
                    arr1.add("B");
                    arr1.add("C");

                    // arr1 عدد عناصرها يساوي عدد عناصر الكائن ,Object نوعها ,arr2 هنا قمنا بإنشاء مصفوفة إسمها
                    Object[] arr2 = new Object[arr1.size()];

                    // arr2 بنفس الترتيب في المصفوفة arr1 هنا قمنا بنسخ عناصر الكائن
                    arr1.toArray(arr2);

                    // arr2 هنا أنشأنا حلقة تعرض جميع العناصر الموجودة في الحلقة
                    for(int i=0; i<arr2.length; i++) {
                    System.out.println("arr2[" +i+ "] = " +arr2[i]);
                    }

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    arr2[0] = A
                    arr2[1] = B
                    arr2[2] = C
                  


المثال السادس

في المثال التالي قمنا بإنشاء نسخة ثانية من كائن الـ LinkedList في كائن جديد نوعه Object بواسطة الدالة clone(), بعدها قمنا بمسح كائن الـ LinkedList الأصلي.

إنتبه: النسخة التي أنشأناها هنا تعتبر مجرد صورة للأشياء الموجودة في كائن الـ LinkedList.

Main.java
                    import java.util.LinkedList;    // LinkedList هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // arr إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
                    LinkedList arr = new LinkedList();

                    // arr هنا قمنا بإضافة 3 عناصر في الكائن
                    arr.add("A");
                    arr.add("B");
                    arr.add("C");

                    // o في الكائن arr هنا قمنا بنسخ عناصر الكائن
                    Object o = arr.clone();

                    // arr هنا قمنا بمسح جميع عناصر الكائن
                    arr.clear();

                    // o و arr هنا قمنا بعرض عناصر كل من الكائنات
                    System.out.println("arr = " +arr);
                    System.out.println("o   = " +o);

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    arr = []
                    o   = [A, B, C] 
                  


المثال السابع

في المثال التالي قمنا بتحديد نوع الكائنات التي يمكن إدخالها في كائنات الـ LinkedList من خلال تطبيق مبدأ الـ Generics.

ملاحظة: سنشرح الـ Generics في درس خاص و هذا مجرد مثال بسيط.

Main.java
                    import java.util.LinkedList;    // LinkedList هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // يمكنه تخزين كائنات من أي نوع كان arr1 إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
                    LinkedList arr1 = new LinkedList();

                    // فقط String يمكنه تخزين كائنات من النوع arr2 إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
                    LinkedList<String> arr2 = new LinkedList<>();

                      // فقط Integer يمكنه تخزين كائنات من النوع arr3 إسمه LinkedList هنا قمنا بإنشاء كائن من الكلاس
                      LinkedList<Integer> arr3 = new LinkedList<>();


                        // arr1 هنا قمنا بإضافة 5 عناصر لها أنواع مختلفة في الكائن
                        arr1.add(null);
                        arr1.add(true);
                        arr1.add(1234);
                        arr1.add("java");
                        arr1.add('A');

                        // arr2 في الكائن String هنا قمنا بإضافة 3 عناصر نوعها
                        arr2.add("A");
                        arr2.add("B");
                        arr2.add("C");

                        // arr3 في الكائن int هنا قمنا بإضافة 3 عناصر نوعها
                        arr3.add(1);
                        arr3.add(2);
                        arr3.add(3);


                        // arr1 هنا قمنا بعرض عناصر الكائن
                        System.out.println("arr1: " +arr1);

                        // arr2 هنا قمنا بعرض عناصر الكائن
                        System.out.println("arr2: " +arr2);

                        // arr3 هنا قمنا بعرض عناصر الكائن
                        System.out.println("arr3: " +arr3);

                        }

                        }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    arr1: [null, true, 1234, java, A]
                    arr2: [A, B, C]
                    arr3: [1, 2, 3]
                  
__________&&&______;&&&___________;&&&&________;

 الكلاس HashSet في جافا

مقدمة

الكلاس HashSet يستخدم لتخزين عناصر متتالية, دون مراعاة أي دقة في ترتيب هذه العناصر, كما أنه يسمح بتخزين القيمة null.
لكنه لا يسمح بتخزين أكثر من عنصر عندهم نفس القيمة, فتجد كل عنصر فيه يملك قيمة مختلفة.

السبب الوحيد الذي قد يجعلك تستخدم هذا الكلاس هو سرعته العالية في التخزين مقارنة مع باقي الكلاسات الموجودة في المجموعة Set.

هنا لا يمكنك الوصول لعنصر محدد من عناصر كائن الـ HashSet لأن العناصر هنا لا تملك أرقام Index. لذلك لا يحتوي على أي دالة من دوال get().
إذاً هنا للوصول إلى عنصر ما عليك المرور على جميع العناصر الأخرى الموجودة في كائن الـ HashSet.


سبب سرعة الأداء

كل عنصر يضاف في كائن الـ HashSet يملك hashcode خاص فيه في الذاكرة.
عندما تحاول على سبيل المثال تخزين عناصر كائن نوعه HashSet في كائن نوعه Iterator, سيتم الوصول لعناصر كائن الـ HashSet مباشرةً من خلال الـ Hash Code الخاص لكل عنصر.


بناؤه
                  public class HashSet<E>
                  extends AbstractSet<E>
                  implements Set<E>, Cloneable, Serializable
                

إذاً الكلاس HashSet يرث من الكلاس AbstractSet, و يطبق الإنترفيسات Set - Cloneable - Serializable.

كونستركتورات الكلاس HashSet

الجدول التالي يحتوي على جميع الكونستركتورات الموجودين في الكلاس HashSet.

الكونستركتور مع تعريفه
public HashSet() هذا الكونستركتور الإفتراضي في الكلاس HashSet, يستخدم لإنشاء كائن نوعه HashSet ليس له حجم محدد.
public HashSet(int initialCapacity) يستخدم هذا الكونستركتور لتحديد حجم كائن الـ ArrayList الأولي.
الرقم الذي نضعه كـ Argument في هذا الكونستركتور يحدد عدد عناصر كائن الـ ArrayList الذي يمكنه احتوائهم على الأقل.
public HashSet(int capacity, float fillRatio) يستخدم هذا الكونستركتور لتحديد حجم كائن الـ HashSet الأولي الذي نريده أن يحجز له في الذاكرة.
الرقم الذي نضعه مكان الباراميتر capacity يحدد عدد العناصر التي يمكن أن يحتويها كائن الـ HashSet, و تذكر أن حجمه يزيد عند الحاجة.
الرقم الذي نضعه مكان الباراميتر fillRatio يمكن أن يكون بين 0.0f و 1.0f.
هنا يتم ضرب المتغيرين capacity و fillRatio ببعضهم, ناتج عملية الضرب يحدد متى سيتم زيادة حجم كائن الـ HashSet في الذاكرة.
public HashSet(Collection c) يستخدم هذا الكونستركتور لإنشاء كائن نوعه HashSet يحتوي على عناصر كائن الـ Collection الذي نمرره له كـ Argument.

دوال الكلاس HashSet

الجدول التالي يحتوي على جميع دوال الكلاس HashSet.

الدالة مع تعريفها
public boolean add(Object o) تضيف عنصر جديد في كائن الـ HashSet.
ترجع true إذا تمت الإضافة بنجاح.
public void clear() تمسح جميع العناصر الموجودة في كائن الـ HashSet.
public Object clone() تنشئ نسخة من كائن الـ HashSet.
public boolean contains(Object o) ترجع true إذا كان كائن الـ HashSet يحتوي على القيمة التي نضعها لها كـ Argument.
public boolean isEmpty() ترجع true في حال كان كائن الـ HashSet فارغاً.
public boolean remove(Object o) تحذف عنصر محدد من كائن الـ HashSet و ترجعه.
ترجع true إذا تم حذف الكائن بنجاح, غير ذلك ترجع false.
public int size() ترجع عدد العناصر الموجودة في كائن الـ HashSet.
public Iterator iterator() ترجع كائن نوعه Iterator يحتوي على جميع عناصر كائن الـ HashSet.
مثال شامل

في المثال التالي قمنا بتعريف كائن نوعه HashSet, إسمه hs, ثم أدخلنا فيه 6 عناصر.

بعدها قمنا بعرض عناصر الكائن hs, ثم عرضنا عددهم.


Main.java
                    import java.util.HashSet;   // HashSet هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // hs إسمه HashSet هنا قمنا بإنشاء كائن من الكلاس
                    HashSet hs = new HashSet();

                    // hs هنا قمنا بإدخال 6 عناصر في الكائن
                    hs.add("A");
                    hs.add("B");
                    hs.add("C");
                    hs.add("D");
                    hs.add("E");
                    hs.add("F");

                    // hs هنا قمنا بعرض عدد عناصر الكائن
                    System.out.println("All elements: " + hs + "\n");

                    // لاحظ أنه لم يتم تخزينهم بالترتيب الذي أدخلناهم فيه .hs هنا قمنا بعرض عناصر الكائن
                    System.out.println("Number of elements: " + hs.size());

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    All elements: [D, E, F, A, B, C]

                    Number of elements: 6 
                  
__________&&&______;&&&___________;&&&&________;

 الكلاس LinkedHashSet في جافا

مقدمة

الكلاس LinkedHashSet يرث من الكلاس HashSet تم تصميمه فقط للحفاظ على ترتيب العناصر التي يتم إدخالها فيه.
و هو يملك نفس الأشياء التي يملكها الكلاس HashSet.

إذاً الكلاس LinkedHashSet يستخدم لتخزين عناصر متتالية, و الحفاظ على الترتيب الذي تم فيه إدخال هذه العناصر, كما أنه يسمح بتخزين القيمة null.
لكنه لا يسمح بتخزين أكثر من عنصر عندهم نفس القيمة, فتجد كل عنصر فيه يملك قيمة مختلفة.

هنا لا يمكنك الوصول لعنصر محدد من عناصر كائن الـ LinkedHashSet لأن العناصر هنا لا تملك أرقام Index. لذلك لا يحتوي على أي دالة من دوال get().
إذاً هنا للوصول إلى عنصر ما عليك المرور على جميع العناصر الأخرى الموجودة في كائن الـ LinkedHashSet.


بناؤه
                  public class LinkedHashSet<E>
                  extends HashSet<E>
                  implements Set<E>, Cloneable, Serializable
                

إذاً الكلاس HashSet يرث من الكلاس AbstractSet, و يطبق الإنترفيسات Set - Cloneable - Serializable.

كونستركتورات الكلاس LinkedHashSet

الجدول التالي يحتوي على جميع الكونستركتورات الموجودين في الكلاس LinkedHashSet.

الكونستركتور مع تعريفه
public LinkedHashSet() هذا الكونستركتور الإفتراضي في الكلاس LinkedHashSet, يستخدم لإنشاء كائن نوعه LinkedHashSet ليس له حجم محدد.
public LinkedHashSet(int initialCapacity) يستخدم هذا الكونستركتور لتحديد حجم كائن الـ ArrayList الأولي.
الرقم الذي نضعه كـ Argument في هذا الكونستركتور يحدد عدد عناصر كائن الـ ArrayList الذي يمكنه احتوائهم على الأقل.
public LinkedHashSet(int capacity, float fillRatio) يستخدم هذا الكونستركتور لتحديد حجم كائن الـ LinkedHashSet الأولي الذي نريده أن يحجز له في الذاكرة.
الرقم الذي نضعه مكان الباراميتر capacity يحدد عدد العناصر التي يمكن أن يحتويها كائن الـ LinkedHashSet, و تذكر أن حجمه يزيد عند الحاجة.
الرقم الذي نضعه مكان الباراميتر fillRatio يمكن أن يكون بين 0.0f و 1.0f.
هنا يتم ضرب المتغيرين capacity و fillRatio ببعضهم, ناتج عملية الضرب يحدد متى سيتم زيادة حجم كائن الـ LinkedHashSet في الذاكرة.
public LinkedHashSet(Collection c) يستخدم هذا الكونستركتور لإنشاء كائن نوعه LinkedHashSet يحتوي على عناصر كائن الـ Collection الذي نمرره له كـ Argument.

دوال الكلاس LinkedHashSet

الجدول التالي يحتوي على جميع دوال الكلاس LinkedHashSet.

الدالة مع تعريفها
public boolean add(Object o) تضيف عنصر جديد في كائن الـ LinkedHashSet.
ترجع true إذا تمت الإضافة بنجاح.
public void clear() تمسح جميع العناصر الموجودة في كائن الـ LinkedHashSet.
public Object clone() تنشئ نسخة من كائن الـ LinkedHashSet.
public boolean contains(Object o) ترجع true إذا كان كائن الـ LinkedHashSet يحتوي على القيمة التي نضعها لها كـ Argument.
public boolean isEmpty() ترجع true في حال كان كائن الـ LinkedHashSet فارغاً.
public boolean remove(Object o) تحذف عنصر محدد من كائن الـ LinkedHashSet و ترجعه.
ترجع true إذا تم حذف الكائن بنجاح, غير ذلك ترجع false.
public int size() ترجع عدد العناصر الموجودة في كائن الـ LinkedHashSet.
public Iterator iterator() ترجع كائن نوعه Iterator يحتوي على جميع عناصر كائن الـ LinkedHashSet.
مثال شامل

في المثال التالي قمنا بتعريف كائن نوعه LinkedHashSet, إسمه lhs, ثم أدخلنا فيه 6 عناصر.

بعدها قمنا بعرض عناصر الكائن lhs, ثم عرضنا عددهم.


Main.java
                    import java.util.LinkedHashSet;   // LinkedHashSet هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // lhs إسمه LinkedHashSet هنا قمنا بإنشاء كائن من الكلاس
                    LinkedHashSet lhs = new LinkedHashSet();

                    // lhs هنا قمنا بإدخال 6 عناصر في الكائن
                    lhs.add("A");
                    lhs.add("B");
                    lhs.add("C");
                    lhs.add("D");
                    lhs.add("E");
                    lhs.add("F");

                    // lhs هنا قمنا بعرض عدد عناصر الكائن
                    System.out.println("All elements: " + lhs + "\n");

                    // لاحظ أنه لم يتم تخزينهم بالترتيب الذي أدخلناهم فيه .hs هنا قمنا بعرض عناصر الكائن
                    System.out.println("Number of elements: " + lhs.size());

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    All elements: [A, B, C, D, E, F]

                    Number of elements: 6 
                  
__________&&&______;&&&___________;&&&&________;

 الكلاس TreeSet في جافا

مقدمة

الكلاس TreeSet يعتبر الكلاس الأكثر تطوراً بين كلاسات المجموعة Set, و هو يستخدم لتخزين عناصر متتالية, و ترتيبهم بالطريقة التي تريد, كما أنه يسمح بتخزين القيمة null, لكنه لا يسمح بتخزين أكثر من عنصر عندهم نفس القيمة, فتجد كل عنصر فيه يملك قيمة مختلفة. و هو يحتوي على دوال أخرى تسهل طريقة الوصول للعناصر.


طريقة ترتيب العناصر

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

كما يمكنك تحديد طريقة ترتيب العناصر بنفسك.


بناؤه
                  public class TreeSet<E>
                  extends AbstractSet<E>
                  implements NavigableSet<E>, Cloneable, Serializable
                

إذاً الكلاس TreeSet يرث من الكلاس AbstractSet, و يطبق الإنترفيسات NavigableSet - Cloneable - Serializable.

كونستركتورات الكلاس TreeSet

الجدول التالي يحتوي على جميع الكونستركتورات الموجودين في الكلاس TreeSet.

الكونستركتور مع تعريفه
public TreeSet() هذا الكونستركتور الإفتراضي في الكلاس TreeSet, يستخدم لإنشاء كائن نوعه TreeSet فارغ يرتب العناصر التي يتم إدخالها فيه بشكل تصاعدي Ascending.
public TreeSet(Collection c) يستخدم هذا الكونستركتور لإنشاء كائن نوعه TreeSet يحتوي على عناصر كائن الـ Collection الذي نمرره له كـ Argument.
public TreeSet(SortedSet ss) يستخدم هذا الكونستركتور لإنشاء كائن نوعه TreeSet يحتوي على عناصر كائن الـ SortedSet الذي نمرره له كـ Argument.
public TreeSet(Comparator c) يستخدم هذا الكونستركتور لإنشاء كائن نوعه TreeSet فارغ يرتب العناصر التي يتم إدخالها فيه على أساس كائن الـ Comparator الذي نمرره له كـ Argument.
إذاً c عبارة عن كائن نوعه Comparator يمثل الطريقة التي سيعتمدها كائن الـ TreeSet في مقارنة قيم عناصره.

دوال الكلاس TreeSet

الجدول التالي يحتوي على جميع دوال الكلاس TreeSet.

الدالة مع تعريفها
public boolean add(Object o) تضيف عنصر جديد في كائن الـ TreeSet.
ترجع true إذا تمت الإضافة بنجاح.
public boolean addAll(Collection c) تضيف جميع عناصر الكائن c في آخر كائن الـ TreeSet.
ترجع true إذا تمت الإضافة بنجاح.
ترمي الإستثناء NullPointerException في حال كان الكائن c فارغاً.
public boolean remove(Object o) تحذف عنصر محدد من كائن الـ TreeSet و ترجعه.
ترجع true إذا تم حذف الكائن بنجاح, غير ذلك ترجع false.
public void clear() تمسح جميع العناصر الموجودة في كائن الـ TreeSet.
public Object clone() تنشئ نسخة من كائن الـ TreeSet.
public boolean contains(Object o) ترجع true في حال كان كائن الـ TreeSet يحتوي على القيمة التي نضعها لها كـ Argument.
public boolean isEmpty() ترجع true في حال كان كائن الـ TreeSet فارغاً.
public int size() ترجع عدد العناصر الموجودة في كائن الـ TreeSet.
public Object first() ترجع قيمة أول عنصر موجود في كائن الـ TreeSet.
ملاحظة: قيمته ستكون أصغر قيمة لأن العناصر في هذا الكائن تترتب فيه بشكل تصاعدي.
public Object last() ترجع قيمة آخر عنصر موجود في كائن الـ TreeSet.
ملاحظة: قيمته ستكون أكبر قيمة لأن العناصر في هذا الكائن تترتب فيه بشكل تصاعدي.
public SortedSet headSet(Object end) ترجع كائن نوعه SortedSet يحتوي على جميع عناصر كائن الـ TreeSet الذي قام باستدعائها الموجودة فيه قبل الكائن end.
public SortedSet tailSet(Object Start) ترجع كائن نوعه SortedSet يحتوي على جميع عناصر كائن الـ TreeSet الذي قام باستدعائها إبتداءاً من الكائن start حتى آخر عنصر موجود فيه.
public SortedSet subSet(Object start, Object end) ترجع كائن نوعه SortedSet يحتوي على جميع عناصر كائن الـ TreeSet الذي قام باستدعائها إبتداءاً من الكائن start وصولاً إلى الكائن end.
public Comparator comparator() ترجع كائن نوعه Comparator يمثل الإنترفيس المستخدم في مقارنة العناصر.
ترجع null في حال لم تقم بتغيير الإنترفيس الإفتراضي.
public Iterator iterator() ترجع كائن نوعه Iterator يحتوي على جميع عناصر كائن الـ TreeSet.
مثال شامل

في المثال التالي قمنا بإنشاء كائن من الكلاس TreeSet, إسمه ts, أدخلنا فيها 5 عناصر عبارة عن أرقام.
بعدها قمنا باستخدام بعض الدوال التي ذكرناها في الجدول السابق.


Main.java
                    import java.util.TreeSet;   // TreeSet هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // ts إسمه TreeSet هنا قمنا بإنشاء كائن من الكلاس
                    TreeSet ts = new TreeSet();

                    // تعمدنا عدم ترتيب القيم من الأصغر إلى الأكبر حتى ترى أنه سيرتبهم بشكل تلقائي .ts هنا قمنا بإضافة 5 قيم في الكائن
                    ts.add(4);
                    ts.add(2);
                    ts.add(5);
                    ts.add(3);
                    ts.add(1);

                    // لاحظ أنه قام بترتيبهم من الأصغر إلى الأكبر .ts هنا قمنا بعرض عناصر الكائن
                    System.out.println("All elements : " + ts);

                    // ts هنا قمنا بعرض أول عنصر موجود في الكائن
                    System.out.println("First element: " + ts.first());

                    // ts هنا قمنا بعرض آخر عنصر موجود في الكائن
                    System.out.println("Last element : " + ts.last());

                    // '3' الموجودة قبل العنصر الذي يملك القيمة ts هنا قمنا بعرض جميع عناصر الكائن
                    System.out.println("headSet(3)   : " + ts.headSet(3));

                    // '3' إبتداءاً من العنصر الذي يملك القيمة ts هنا قمنا بعرض جميع عناصر الكائن
                    System.out.println("tailSet(3)   : " + ts.tailSet(3));

                    // 'إبتداءاً من العنصر الذي يملك القيمة '1' وصولاً إلى ما قبل العنصر الذي يملك القيمة '4 ts هنا قمنا بعرض جميع عناصر الكائن
                    System.out.println("Subset(1,4)  : " + ts.subSet(1, 4));

                    // هنا قمنا بعرض الإنترفيس المستخدم في مقارنة العناصر
                    System.out.println("Comparator() : " + ts.comparator());

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    All elements : [1, 2, 3, 4, 5]
                    First element: 1
                    Last element : 5
                    headSet(3)   : [1, 2]
                    tailSet(3)   : [3, 4, 5]
                    Subset(1,4)  : [1, 2, 3]
                    Comparator() : null
                  
__________&&&______;&&&___________;&&&&________;

 الإنترفيس Map في جافا

مقدمة

الإنترفيس Map يتيح لك تخزين العناصر بشكل Key / Value.
هنا كل عنصر يتم تخزينه يملك كائنين: الأول عبارة عن مفتاح ( key ) و الثاني عبارة قيمة ( value ).

للوصول إلى أي عنصر, سواء لحذفه أو إعطائه قيمة جديدة نستخدم المفتاح له.


نظرة عامة
  • بشكل عام, يستخدم لتخزين العناصر بشكل Key / Value.

  • يمكن للمفاتيح المختلفة أن تحتوي على نفس القيمة.

  • بعض الدوال التي يملكها ترمي الإستثناء UnsupportedOperationException إذا تم استخدامهم بطريقة خاطئة.

  • يرمى الإستثناء ClassCastException في حال كان لا يمكن تحويل نوع الكائن إلى نوع آخر.

  • يرمى الإستثناء NullPointerException في حال تم إضافة القيمة null فيه لأنه لا يقبل القيمة null.

  • يرمى الإستثناء NoSuchElementException في حال كان كائن الـ Map فارغاً و كنت تحاول إرجاع قيمة عنصر من عناصره.

دوال الإنترفيس Map

الجدول التالي يحتوي على دوال الإنترفيس Map.

الدالة مع تعريفها
public void clear() تمسح جميع العناصر الموجودة في الكائن الذي قام باستدعائها.
public boolean containsKey(Object key) ترجع true إذا كان الكائن الذي قام باستدعائها يحتوي على الكائن key الذي نضعه لها كـ Argument كمفتاح فيه.
public boolean containsValue(Object value) ترجع true إذا كان الكائن الذي قام باستدعائها يحتوي على الكائن value الذي نضعه لها كـ Argument كقيمة فيه.
public boolean equals(Object obj) ترجع true في حال كان الكائن الذي قام باستدعائها يتطابق مع الكائن الذي نمرره لها كـ Argument.
public Object get(Object key) ترجع قيمة المفتاح الذي نمرره لها كـ Argument.
في حال كان كائن الكائن الذي قام باستدعائها لا يحتوي على المفتاح الذي مررناه لها, ترجع القيمة null.
public int hashCode() ترجع الـ Hash Code للكائن الذي قام باستدعائها.
public boolean isEmpty() ترجع true في حال كان الكائن الذي قام باستدعائها فارغاً.
public Set keySet() ترجع كائن نوعه Set يحتوي على جميع مفاتيح الكائن الذي قام باستدعائها.
public Object put(Object key, Object value) تستخدم لإضافة عنصر جديد في الكائن الذي قام باستدعائها مع تحديد مفتاح الوصول إليه و قيمته.
  • key هو كائن يمثل مفتاح العنصر.

  • value هو كائن يمثل قيمة العنصر.

public void putAll(Map m) تضيف جميع عناصر الكائن m الذي نمرره لها كـ Argument في الكائن الذي قام باستدعائها.
public Object remove(Object key) تحذف العنصر الذي يملك المفتاح الذي نمرره لها كـ Argument.
public int size() ترجع عدد العناصر الموجودة في الكائن الذي قام باستدعائها.
public Collection values() ترجع كائن نوعه Collection يحتوي على جميع قيم الكائن الذي قام باستدعائها.
مثال شامل

في المثال التالي قمنا بإنشاء ثلاث كائنات من ثلاث كلاسات مختلفة ترث من الإنترفيس Map.
لاحظ أننا استخدمنا الدالة put() التي ورثتها الكائنات في الأساس من الإنترفيس Map.


Main.java
                    import java.util.Map;
                    import java.util.TreeMap;
                    import java.util.HashMap;
                    import java.util.LinkedHashMap;

                    public class Main {

                    public static void main(String[] args) {

                    // وضعنا فيه ثلاث عناصر m1 إسمه TreeMap هنا قمنا بإنشاء كائن من الكلاس
                    Map m1 = new TreeMap();
                    m1.put(1, "Ayoub");
                    m1.put(2, "Salem");
                    m1.put(3, "Rayan");

                    // وضعنا فيه ثلاث عناصر m2 إسمه HashMap هنا قمنا بإنشاء كائن من الكلاس
                    Map m2 = new HashMap();
                    m2.put(1, "Mona");
                    m2.put(2, "Rima");
                    m2.put(3, "Hana");

                    // وضعنا فيه ثلاث عناصر m3 إسمه LinkedHashMap هنا قمنا بإنشاء كائن من الكلاس
                    Map m3 = new LinkedHashMap();
                    m3.put(1, "Jhony");
                    m3.put(2, "Ahmad");
                    m3.put(3, "Jihad");

                    // m3 و m2 و m1 هنا قمنا بعرض محتويات الكائنات
                    System.out.println("TreeMap keys/values:       " + m1);
                    System.out.println("HashMap keys/values:       " + m2);
                    System.out.println("LinkedHashMap keys/values: " + m3);

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    TreeMap keys/values:       {1=Ayoub, 2=Salem, 3=Rayan}
                    HashMap keys/values:       {1=Mona, 2=Rima, 3=Hana}
                    LinkedHashMap keys/values: {1=Jhony, 2=Ahmad, 3=Jihad} 
                  
__________&&&______;&&&___________;&&&&________;

 الإنترفيس SortedMap في جافا

مقدمة

الإنترفيس SortedMap يرث من الإنترفيس Map. تم بناءه لتخزين العناصر بشكل Key / Value, و بترتيب تصاعدي ( Ascending ).

إذاً هنا كل عنصر يتم تخزينه يملك كائنين: الأول عبارة عن مفتاح ( key ) و الثاني عبارة قيمة ( value ).

في حال كانت قيم العناصر تمثل أرقام, عندها يتم ترتيبهم من العدد الأصغر إلى العدد الأكبر.
في حال كانت قيم العناصر تمثل نصوص أو كلمات أو أحرف, عندها يتم ترتيبهم ترتيباً أبجدياً.

كما أنه يحتوي على دوال جديدة غير موجودة في الإنترفيس Map.


نظرة عامة
  • بشكل عام, يستخدم لتخزين العناصر بشكل Key / Value.

  • يمكن للمفاتيح المختلفة أن تحتوي على نفس القيمة.

  • يملك دواله الخاصة إضافةً إلى الدوال التي ورثها من الإنترفيس Map.

  • بعض الدوال التي يملكها ترمي الإستثناء UnsupportedOperationException إذا تم استخدامهم بطريقة خاطئة.

  • يرمى الإستثناء ClassCastException في حال كان لا يمكن تحويل نوع الكائن إلى نوع آخر.

  • يرمى الإستثناء NullPointerException في حال تم إضافة القيمة null فيه لأنه لا يقبل القيمة null.

  • يرمى الإستثناء NoSuchElementException في حال كان كائن الـ SortedMap فارغاً و كنت تحاول إرجاع قيمة عنصر من عناصره.

دوال الإنترفيس SortedMap

الجدول التالي يحتوي على دوال الإنترفيس SortedMap.

الدالة مع تعريفها
public Object firstKey() ترجع مفتاح أول عنصر موجود في الكائن الذي قام باستدعائها.
ملاحظة: قيمته ستكون أصغر قيمة لأن العناصر في هذا الكائن تترتب فيه بشكل تصاعدي.
public Object lastKey() ترجع مفتاح آخر عنصر موجود في الكائن الذي قام باستدعائها.
ملاحظة: قيمته ستكون أكبر قيمة لأن العناصر في هذا الكائن تترتب فيه بشكل تصاعدي.
public SortedMap headMap(Object end) ترجع كائن نوعه SortedMap يحتوي على جميع عناصر الكائن الذي قام باستدعائها الموجودة قبل الكائن end.
public SortedMap tailMap(Object Start) ترجع كائن نوعه SortedMap يحتوي على جميع عناصر الكائن الذي قام باستدعائها إبتداءاً من الكائن start حتى آخر عنصر موجود فيه.
public SortedMap subMap(Object start, Object end) ترجع كائن نوعه SortedMap يحتوي على جميع عناصر الكائن الذي قام باستدعائها إبتداءاً من الكائن start وصولاً إلى الكائن end.
public Comparator comparator() ترجع كائن نوعه Comparator يمثل الإنترفيس المستخدم في مقارنة العناصر.
ترجع null في حال لم تقم بتغيير الإنترفيس الإفتراضي.

مثال شامل

في المثال التالي قمنا بإنشاء كائن من الكلاس TreeMap و الذي يرث من الإنترفيس SortedMap.
و قمنا باستخدام جميع دواله التي ذكرناها في الجدول السابق.


Main.java
                    import java.util.TreeMap;
                    import java.util.SortedMap;

                    public class Main {

                    public static void main(String[] args) {

                    // sm إسمه TreeSet هنا قمنا بإنشاء كائن من الكلاس
                    SortedMap sm = new TreeMap();

                    // تعمدنا عدم ترتيب القيم من الأصغر إلى الأكبر حتى ترى أنه سيرتبهم بشكل تلقائي .sm هنا قمنا بإضافة 5 قيم في الكائن
                    sm.put(11, "Rola");
                    sm.put(7, "Rayan");
                    sm.put(15, "Sami");
                    sm.put(2, "Ahmad");
                    sm.put(6, "Mira");

                    // لاحظ أنه قام بترتيبهم من الأصغر إلى الأكبر .sm هنا قمنا بعرض عناصر الكائن
                    System.out.println("All keys/values: " + sm);

                    // '8' الموجودة قبل المفتاح sm هنا قمنا بعرض جميع عناصر الكائن
                    System.out.println("headMap(8):      " + sm.headMap(8));

                    // '8' إبتداءاً من المفتاح sm هنا قمنا بعرض جميع عناصر الكائن
                    System.out.println("tailMap(8):      " + sm.tailMap(8));

                    // 'إبتداءاً من المفتاح '1' وصولاً إلى المفتاح '10 sm هنا قمنا بعرض جميع عناصر الكائن
                    System.out.println("subMap(1,10):    " + sm.subMap(1, 10));

                    // sm هنا قمنا بعرض أول مفتاح موجود في الكائن
                    System.out.println("First key:       " + sm.firstKey());

                    // sm هنا قمنا بعرض آخر مفتاح موجود في الكائن
                    System.out.println("Last key:        " + sm.lastKey());

                    // هنا قمنا بعرض الإنترفيس المستخدم في مقارنة العناصر
                    System.out.println("Comparator():    " + sm.comparator());

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    All keys/values: {2=Ahmad, 6=Mira, 7=Rayan, 11=Rola, 15=Sami}
                    headMap(8):      {2=Ahmad, 6=Mira, 7=Rayan}
                    tailMap(8):      {11=Rola, 15=Sami}
                    subMap(1,10):    {2=Ahmad, 6=Mira, 7=Rayan}
                    First key:       2
                    Last key:        15
                    Comparator():    null
                  
__________&&&______;&&&___________;&&&&________;

 الكلاس HashMap في جافا

مقدمة

الكلاس HashMap يستخدم لتخزين العناصر بشكل Key / Value حيث يتم إعطاء مفتاح لكل قيمة يتم تخزينها بداخل الـ HashMap.

هنا كل قيمة يتم تخزينها في كائن الـ HashMap يجب إعطاءها Key غير مستخدم, لأن كل Key موضوع يسمح لك بالوصول لقيمة واحدة من القيم الموجودة في كائن الـ HashMap.

إذاً الـ HashMap كأنه جدول يتألف من عامودين, الأول يحتوي المفاتيح ( Keys ) و الثاني يحتوي على القيم ( Values ).

خلاصة, كل عنصر يضاف في الـ HashMap يجب أن يحتوي على كائنين, الأول يمثل المفتاح و الثاني يمثل قيمته.

ملاحظة: الـ HashMap يمكنه إمتلاك مفتاح واحد نوعه null, و يمكن وضع القيمة null كقيمة لأي مفتاح موجود فيه.


بناؤه
                  public class HashMap<K,V>
                  extends AbstractMap<K,V>
                  implements Map<K,V>, Cloneable, Serializable
                
  • K يقصد بها نوع الكائنات التي تمثل مفاتيح.

  • V يقصد بها نوع الكائنات التي تمثل قيم.

إذاً الكلاس HashMap يرث من الكلاس AbstractMap, و يطبق الإنترفيسات Map - Cloneable - Serializable.

كونستركتورات الكلاس HashMap

الجدول التالي يحتوي على جميع الكونستركتورات الموجودين في الكلاس HashMap.

الكونستركتور مع تعريفه
public HashMap() هذا الكونستركتور الإفتراضي في الكلاس HashMap, يستخدم لإنشاء كائن نوعه HashMap ليس له حجم محدد.
إذاً في البداية يكون حجمه يساوي 0 لكنه يزيد كلما أضفنا فيه عنصر جديد.
public HashMap(int size) يستخدم هذا الكونستركتور لتحديد حجم كائن الـ HashMap الأولي الذي نريده أن يحجز له في الذاكرة.
الرقم الذي نضعه كـ Argument في هذا الكونستركتور يحدد عدد العناصر التي يمكن أن يحتويها كائن الـ HashMap, و تذكر أن حجمه يزيد عند الحاجة.
public HashMap(int size, float fillRatio) يستخدم هذا الكونستركتور لتحديد حجم كائن الـ HashMap الأولي الذي نريده أن يحجز له في الذاكرة.
الرقم الذي نضعه مكان الباراميتر size يحدد عدد العناصر التي يمكن أن يحتويها كائن الـ HashMap, و تذكر أن حجمه يزيد عند الحاجة.
الرقم الذي نضعه مكان الباراميتر fillRatio يمكن أن يكون بين 0.0f و 1.0f.
هنا يتم ضرب المتغيرين size و fillRatio ببعضهم, ناتج عملية الضرب يحدد متى سيتم زيادة حجم كائن الـ HashMap في الذاكرة.
public HashMap(Map m) يستخدم هذا الكونستركتور لإنشاء كائن نوعه HashMap يحتوي على عناصر كائن الـ Map الذي نمرره له كـ Argument.

دوال الكلاس HashMap

الجدول التالي يحتوي على جميع دوال الكلاس HashMap.

الدالة مع تعريفها
public Object put(Object key, Object value) تستخدم لإضافة عنصر جديد في كائن الـ HashMap.
  • key عبارة عن كائن يمثل مفتاح العنصر.

  • value عبارة عن كائن يمثل قيمة العنصر.

public Object putAll(Map m) تضيف جميع عناصر الكائن m الذي نمرره لها كـ Argument في كائن الـ HashMap.
public Object remove(Object key) تحذف العنصر الذي يملك المفتاح الذي نمرره لها كـ Argument.
public void clear() تمسح جميع العناصر الموجودة في كائن الـ HashMap.
public Object clone() تنشئ نسخة من كائن الـ HashMap.
public Object get(Object key) ترجع قيمة المفتاح الذي نمرره لها كـ Argument.
في حال كان كائن الـ HashMap لا يحتوي على المفتاح الذي مررناه لها, ترجع القيمة null.
public boolean containsValue(Object value) ترجع true إذا كان كائن الـ HashMap يحتوي على القيمة التي نضعها لها كـ Argument تماماً مثل الدالة contains().
معلومة تقنية: هذه الدالة ورثها الكلاس HashMap من الإنترفيس Map, و فعل لها Override لتستدعي الدالة contains() فقط, لذلك لا يوجد أي فرق بينهما.
public boolean containsKey(Object value) ترجع true إذا كان كائن الـ HashMap يحتوي على المفتاح الذي نضعه لها كـ Argument.
public Set entrySet() ترجع كائن نوعه Set يملك جميع عناصر ( مفاتيح + قيم ) الكائن الـ HashMap.
public Set keySet() ترجع كائن نوعه Set يملك جميع مفاتيح الكائن الـ HashMap.
public Collection values() ترجع كائن نوعه Collection يملك جميع قيم الكائن الـ HashMap.
public boolean isEmpty() ترجع true في حال كان كائن الـ HashMap فارغاً.
public int size() ترجع عدد العناصر الموجودة في كائن الـ HashMap.
مثال شامل

في المثال التالي قمنا بتعريف كائن نوعه HashMap, إسمه h, ثم أدخلنا فيه 12 عنصر.

بعدها قمنا بتخزين جميع المفاتيح في كائن نوعه Iterator, إسمه keys.
و قمنا أيضاً بتخزين جميع القيم في كائن نوعه Iterator, إسمه values.

بعدها عرضناهم كجدول يتألف من عامودين من خلال الحلقة while.

في الأخير قمنا بالبحث عن قيمة مفتاح أدخالناه سابقاً.


Main.java
                    import java.util.HashMap;          // HashMap هنا قمنا باستدعاء الكلاس
                    import java.util.iterator;         // iterator هنا قمنا باستدعاء الإنترفيس

                    public class Main {

                    public static void main(String[] args) {

                    // و الذي سنضع فيه كود البلد و إسمه h إسمه HashMap هنا قمنا بإنشاء كائن نوعه
                    HashMap h = new HashMap();

                    // كل عنصر يحتوي على كود البلد كمفتاح و إسمه كقيمة .h هنا قمنا بإضافة 12 عنصر في الكائن
                    h.put("+961", "Lebanon");
                    h.put("+962", "Jordan");
                    h.put("+963", "Syria");
                    h.put("+964", "Iraq");
                    h.put("+965", "Kuwait");
                    h.put("+966", "KSA");
                    h.put("+967", "Yaman");
                    h.put("+968", "Oman");
                    h.put("+970", "Palestine");
                    h.put("+212", "Morocco");
                    h.put("+281", "Libya");
                    h.put("+20",  "Egypt");

                    // أي وضعنا اكواد البلاد فيه .keys بداخل الكائن h هنا قمنا بتخزين جميع مفاتيح الكائن
                    Iterator keys = h.keySet().iterator();

                    // أي وضعنا أسماء البلاد فيه .values بداخل الكائن h هنا قمنا بتخزين جميع قيم الكائن
                    Iterator values = h.values().iterator();

                    System.out.println("The table below contains all Codes & Countries \n");
                    System.out.println("---------------------");
                    System.out.println("Code \t | Country");
                    System.out.println("---------------------");

                    // لا يزال يحتوي على مفاتيح keys هنا أنشأنا حلقة تستمر في تكرار نفسها طالما أن الكائن
                    // الفكرة هنا المرور على جميع المفاتيح الموجودة و عرض كل مفتاح موجود و قيمته
                    while( keys.hasNext() ) {
                    System.out.println(keys.next() + "\t | " + values.next());
                    }
                    System.out.println("---------------------\n");


                    // KSA هنا قمنا بالبحث عن إسم البلد الذي يملك الكود 996+ فكان الجواب
                    System.out.println("Which Country use the code +966 ?");
                    System.out.println(h.get("+966"));

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    The table below contains all Codes & Countries

                    ---------------------
                    Code     | Country
                    ---------------------
                    +281     | Libya
                    +966     | KSA
                    +965     | Kuwait
                    +964     | Iraq
                    +963     | Syria
                    +962     | Jordan
                    +961     | Lebanon
                    +212     | Morocco
                    +20      | Egypt
                    +970     | Palestine
                    +968     | Oman
                    +967     | Yaman
                    ---------------------

                    Which Country use the code +966 ?
                    KSA 
                  
__________&&&______;&&&___________;&&&&________;

 الكلاس LinkedHashMap في جافا

مقدمة

الكلاس LinkedHashMap يرث من الكلاس HashMap تم تصميمه فقط للحفاظ على ترتيب العناصر التي يتم إدخالها فيه.
و هو يملك نفس الأشياء التي يملكها الكلاس HashMap.

الكلاس LinkedHashMap يستخدم لتخزين العناصر بشكل Key / Value و الحفاظ على الترتيب الذي تم فيه إدخال هذه العناصر.

ملاحظة: الـ LinkedHashMap يمكنه إمتلاك مفتاح واحد نوعه null, و يمكن وضع القيمة null كقيمة لأي مفتاح موجود فيه.


بناؤه

                  public class LinkedHashMap<K,V>
                  extends HashMap<K,V>
                  implements Map<K,V>
                
  • K يقصد بها نوع الكائنات التي تمثل مفاتيح.

  • V يقصد بها نوع الكائنات التي تمثل قيم.

إذاً الكلاس LinkedHashMap يرث من الكلاس HashMap, و يطبق الإنترفيسات Map.

كونستركتورات الكلاس LinkedHashMap

الجدول التالي يحتوي على جميع الكونستركتورات الموجودة في الكلاس LinkedHashMap.

الكونستركتور مع تعريفه
LinkedHashMap() هذا الكونستركتور الإفتراضي في الكلاس LinkedHashMap, يستخدم لإنشاء كائن نوعه LinkedHashMap ليس له حجم محدد.
إذاً في البداية يكون حجمه يساوي 0 لكنه يزيد كلما أضفنا فيه عنصر جديد.
LinkedHashMap(int size) يستخدم هذا الكونستركتور لتحديد حجم كائن الـ LinkedHashMap الأولي الذي نريده أن يحجز له في الذاكرة.
الرقم الذي نضعه كـ Argument في هذا الكونستركتور يحدد عدد العناصر التي يمكن أن يحتويها كائن الـ LinkedHashMap, و تذكر أن حجمه يزيد عند الحاجة.
LinkedHashMap(int size, float fillRatio) يستخدم هذا الكونستركتور لتحديد حجم كائن الـ LinkedHashMap الأولي الذي نريده أن يحجز له في الذاكرة.
الرقم الذي نضعه مكان الباراميتر size يحدد عدد العناصر التي يمكن أن يحتويها كائن الـ LinkedHashMap, و تذكر أن حجمه يزيد عند الحاجة.
الرقم الذي نضعه مكان الباراميتر fillRatio يمكن أن يكون بين 0.0f و 1.0f.
هنا يتم ضرب المتغيرين size و fillRatio ببعضهم, ناتج عملية الضرب يحدد متى سيتم زيادة حجم كائن الـ LinkedHashMap في الذاكرة.
LinkedHashMap(int size, float fillRatio, boolean order) يستخدم هذا الكونستركتور لتحديد حجم كائن الـ LinkedHashMap الأولي الذي نريده أن يحجز له في الذاكرة, مع تحديد إذا كنا نريد الحفاظ على ترتيب العناصر التي يتم إدخالها فيه.
الرقم الذي نضعه مكان الباراميتر size يحدد عدد العناصر التي يمكن أن يحتويها كائن الـ LinkedHashMap, و تذكر أن حجمه يزيد عند الحاجة.
الرقم الذي نضعه مكان الباراميتر fillRatio يمكن أن يكون بين 0.0f و 1.0f.
هنا يتم ضرب المتغيرين size و fillRatio ببعضهم, ناتج عملية الضرب يحدد متى سيتم زيادة حجم كائن الـ LinkedHashMap في الذاكرة.
القيمة التي نضعها مكان الباراميتر order تحدد إذا كان سيتم تريتب العناصر في الذاكرة أم لا, إذا مررنا مكانه القيمة true سيتم ترتيبهم.
LinkedHashMap(Map m) يستخدم هذا الكونستركتور لإنشاء كائن نوعه LinkedHashMap يحتوي على عناصر كائن الـ Map الذي نمرره له كـ Argument.

دوال الكلاس LinkedHashMap

الجدول التالي يحتوي على جميع دوال الكلاس LinkedHashMap.

الدالة مع تعريفها
Object put(Object key, Object value) تستخدم لإضافة عنصر جديد في كائن الـ LinkedHashMap.
  • key عبارة عن كائن يمثل مفتاح العنصر.

  • value عبارة عن كائن يمثل قيمة العنصر.

Object putAll(Map m) تضيف جميع عناصر الكائن m الذي نمرره لها كـ Argument في كائن الـ LinkedHashMap.
Object remove(Object key) تحذف العنصر الذي يملك المفتاح الذي نمرره لها كـ Argument.
void clear() تمسح جميع العناصر الموجودة في كائن الـ LinkedHashMap.
Object clone() تنشئ نسخة من كائن الـ LinkedHashMap.
Object get(Object key) ترجع قيمة المفتاح الذي نمرره لها كـ Argument.
في حال كان كائن الـ LinkedHashMap لا يحتوي على المفتاح الذي مررناه لها, ترجع القيمة null.
boolean containsValue(Object value) ترجع true إذا كان كائن الـ LinkedHashMap يحتوي على القيمة التي نضعها لها كـ Argument تماماً مثل الدالة contains().
معلومة تقنية: هذه الدالة ورثها الكلاس LinkedHashMap من الإنترفيس Map, و فعل لها Override لتستدعي الدالة contains() فقط, لذلك لا يوجد أي فرق بينهما.
boolean containsKey(Object value) ترجع true إذا كان كائن الـ LinkedHashMap يحتوي على المفتاح الذي نضعه لها كـ Argument.
Set entrySet() ترجع كائن نوعه Set يملك جميع عناصر ( مفاتيح + قيم ) الكائن الـ LinkedHashMap.
Set keySet() ترجع كائن نوعه Set يملك جميع مفاتيح الكائن الـ LinkedHashMap.
Collection values() ترجع كائن نوعه Collection يملك جميع قيم الكائن الـ LinkedHashMap.
boolean isEmpty() ترجع true في حال كان كائن الـ LinkedHashMap فارغاً.
int size() ترجع عدد العناصر الموجودة في كائن الـ LinkedHashMap.

مثال شامل

في المثال التالي قمنا بتعريف كائن نوعه LinkedHashMap, إسمه lhm, ثم أدخلنا فيه 12 عنصر.

بعدها قمنا بتخزين جميع المفاتيح في كائن نوعه Iterator, إسمه keys.
و قمنا أيضاً بتخزين جميع القيم في كائن نوعه Iterator, إسمه values.

بعدها عرضناهم كجدول يتألف من عامودين من خلال الحلقة while.

في الأخير قمنا بالبحث عن قيمة مفتاح أدخالناه سابقاً.


Main.java
                    import java.util.LinkedHashMap;        // LinkedHashMap هنا قمنا باستدعاء الكلاس
                    import java.util.iterator;             // iterator هنا قمنا باستدعاء الإنترفيس

                    public class Main {

                    public static void main(String[] args) {

                    // و الذي سنضع فيه كود البلد و إسمه lhm إسمه LinkedHashMap هنا قمنا بإنشاء كائن نوعه
                    LinkedHashMap lhm = new LinkedHashMap();

                    // كل عنصر يحتوي على كود البلد كمفتاح و إسمه كقيمة . لاحظ لاحقاً أنه سيتم عرضهم بنفس الترتيب الذي أدخلوا فيه .lhm هنا قمنا بإضافة 12 عنصر في الكائن
                    lhm.put("+961", "Lebanon");
                    lhm.put("+962", "Jordan");
                    lhm.put("+963", "Syria");
                    lhm.put("+964", "Iraq");
                    lhm.put("+965", "Kuwait");
                    lhm.put("+966", "KSA");
                    lhm.put("+967", "Yaman");
                    lhm.put("+968", "Oman");
                    lhm.put("+970", "Palestine");
                    lhm.put("+212", "Morocco");
                    lhm.put("+281", "Libya");
                    lhm.put("+20",  "Egypt");

                    // أي وضعنا اكواد البلاد فيه .keys بداخل الكائن lhm هنا قمنا بتخزين جميع مفاتيح الكائن
                    Iterator keys = lhm.keySet().iterator();

                    // أي وضعنا أسماء البلاد فيه .values بداخل الكائن lhm هنا قمنا بتخزين جميع قيم الكائن
                    Iterator values = lhm.values().iterator();

                    System.out.println("The table below contains all Codes & Countries \n");
                    System.out.println("---------------------");
                    System.out.println("Code \t | Country");
                    System.out.println("---------------------");

                    // لا يزال يحتوي على مفاتيح keys هنا أنشأنا حلقة تستمر في تكرار نفسها طالما أن الكائن
                    // الفكرة هنا المرور على جميع المفاتيح الموجودة و عرض كل مفتاح موجود و قيمته
                    while( keys.hasNext() ) {
                    System.out.println(keys.next() + "\t | " + values.next());
                    }
                    System.out.println("---------------------\n");


                    // KSA هنا قمنا بالبحث عن إسم البلد الذي يملك الكود 996+ فكان الجواب
                    System.out.println("Which Country use the code +966 ?");
                    System.out.println(lhm.get("+966"));

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    The table below contains all Codes & Countries

                    ---------------------
                    Code     | Country
                    ---------------------
                    +961     | Lebanon
                    +962     | Jordan
                    +963     | Syria
                    +964     | Iraq
                    +965     | Kuwait
                    +966     | KSA
                    +967     | Yaman
                    +968     | Oman
                    +212     | Morocco
                    +970     | Palestine
                    +281     | Libya
                    +20      | Egypt
                    ---------------------

                    Which Country use the code +966 ?
                    KSA 
                  
__________&&&______;&&&___________;&&&&________;

 الكلاس TreeMap في جافا

مقدمة

الكلاس TreeMap يعتبر الكلاس الأكثر تطوراً بين كلاسات المجموعة Tree, و هو يستخدم لتخزين العناصر بشكل Key / Value بالإضافة إلى ترتيب هذه العناصر في الذاكرة بشكل تصاعدي Ascending نسبة للـ keys. و هو يحتوي على دوال أخرى تسهل طريقة الوصول للعناصر.

إذاً الـ TreeMap كأنه جدول يتألف من عامودين, الأول يحتوي المفاتيح ( Keys ) و الثاني يحتوي على القيم ( Values ).

هنا كل قيمة يتم تخزينها في كائن الـ TreeMap يجب إعطاءها Key غير مستخدم, لأن كل Key موضوع يسمح لك بالوصول لقيمة واحدة من القيم الموجودة في كائن الـ TreeMap.

خلاصة, كل عنصر يضاف في كائن الـ TreeMap يجب أن يحتوي على كائنين, الأول يمثل المفتاح و الثاني يمثل قيمته.

ملاحظة: كائن الـ TreeMap يمكنه إمتلاك مفتاح واحد نوعه null, و يمكن وضع القيمة null كقيمة لأي مفتاح موجود فيه.


طريقة ترتيب العناصر

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

كما يمكنك تحديد طريقة ترتيب العناصر بنفسك.


بناؤه
                  public class TreeMap<K,V>
                  extends AbstractMap<K,V>
                  implements NavigableMap<K,V>, Cloneable, Serializable
                
  • K يقصد بها نوع الكائنات التي تمثل مفاتيح.

  • V يقصد بها نوع الكائنات التي تمثل قيم.

إذاً الكلاس TreeMap يرث من الكلاس AbstractMap, و يطبق الإنترفيسات NavigableMap - Serializable - Cloneable.

كونستركتورات الكلاس TreeMap

الجدول التالي يحتوي على جميع الكونستركتورات الموجودة في الكلاس TreeMap.

الكونستركتور مع تعريفه
public TreeMap() هذا الكونستركتور الإفتراضي في الكلاس TreeMap, يستخدم لإنشاء كائن نوعه TreeMap فارغ يرتب العناصر التي يتم إدخالها فيه بشكل تصاعدي Ascending.
public TreeMap(Collection c) يستخدم هذا الكونستركتور لإنشاء كائن نوعه TreeMap يحتوي على عناصر كائن الـ Collection الذي نمرره له كـ Argument.
public TreeMap(Map m) يستخدم هذا الكونستركتور لإنشاء كائن نوعه TreeMap يحتوي على عناصر كائن الـ Map الذي نمرره له كـ Argument.
public TreeMap(Comparator c) يستخدم هذا الكونستركتور لإنشاء كائن نوعه TreeMap فارغ يرتب العناصر التي يتم إدخالها فيه على أساس كائن الـ Comparator الذي نمرره له كـ Argument.
إذاً c عبارة عن كائن نوعه Comparator يمثل الطريقة التي سيعتمدها كائن الـ TreeMap في مقارنة قيم عناصره.

دوال الكلاس TreeMap

الجدول التالي يحتوي على جميع دوال الكلاس TreeMap.

الدالة مع تعريفها
public Object put(Object key, Object value) تستخدم لإضافة عنصر جديد في كائن الـ TreeMap.
  • key عبارة عن كائن يمثل مفتاح العنصر.

  • value عبارة عن كائن يمثل قيمة العنصر.

public Object putAll(Map m) تضيف جميع عناصر الكائن m الذي نمرره لها كـ Argument في كائن الـ TreeMap.
public Object remove(Object key) تحذف العنصر الذي يملك المفتاح الذي نمرره لها كـ Argument.
public void clear() تمسح جميع العناصر الموجودة في كائن الـ TreeMap.
public Object clone() تنشئ نسخة من كائن الـ TreeMap.
public Object get(Object key) ترجع قيمة المفتاح الذي نمرره لها كـ Argument.
في حال كان كائن الـ TreeMap لا يحتوي على المفتاح الذي مررناه لها, ترجع القيمة null.
public boolean containsValue(Object value) ترجع true إذا كان كائن الـ TreeMap يحتوي على القيمة التي نضعها لها كـ Argument.
public boolean containsKey(Object value) ترجع true إذا كان كائن الـ TreeMap يحتوي على المفتاح الذي نضعه لها كـ Argument.
public Set entrySet() ترجع كائن نوعه Set يملك جميع عناصر ( مفاتيح + قيم ) الكائن الـ TreeMap.
public Set keySet() ترجع كائن نوعه Set يملك جميع مفاتيح الكائن الـ TreeMap.
public Collection values() ترجع كائن نوعه Collection يملك جميع قيم الكائن الـ TreeMap.
public boolean isEmpty() ترجع true في حال كان كائن الـ TreeMap فارغاً.
public int size() ترجع عدد العناصر الموجودة في كائن الـ TreeMap.
public Object firstKey() ترجع كائن يمثل أول مفتاح key موجود في كائن الـ TreeMap.
ملاحظة: قيمته ستكون أصغر قيمة لأن المفاتيح في هذا الكائن تترتب فيه بشكل تصاعدي.
public Object lastKey() ترجع كائن يمثل آخر مفتاح key موجود في كائن الـ TreeMap.
ملاحظة: قيمته ستكون أكبر قيمة لأن المفاتيح في هذا الكائن تترتب فيه بشكل تصاعدي.
public SortedMap headMap(Object end) ترجع كائن نوعه SortedMap يحتوي على جميع عناصر كائن الـ TreeMap الذي قام باستدعائها الموجودة فيه قبل الكائن end.
public SortedMap tailMap(Object Start) ترجع كائن نوعه SortedMap يحتوي على جميع عناصر كائن الـ TreeMap الذي قام باستدعائها إبتداءاً من الكائن start حتى آخر عنصر موجود فيه.
public SortedMap subMap(Object start, Object end) ترجع كائن نوعه SortedMap يحتوي على جميع عناصر كائن الـ TreeMap الذي قام باستدعائها إبتداءاً من الكائن start وصولاً إلى الكائن end.
public Comparator comparator() ترجع كائن نوعه Comparator يمثل الإنترفيس المستخدم في مقارنة العناصر.
ترجع null في حال لم تقم بتغيير الإنترفيس الإفتراضي.

مثال شامل

في المثال التالي قمنا بتعريف كائن نوعه TreeMap, إسمه tm, ثم أدخلنا فيه 12 عنصر.

بعدها قمنا بتخزين جميع المفاتيح في كائن نوعه Iterator, إسمه keys.
و قمنا أيضاً بتخزين جميع القيم في كائن نوعه Iterator, إسمه values.

بعدها عرضناهم كجدول يتألف من عامودين من خلال الحلقة while.
لاحظ أنه تم عرضهم بترتيب تصاعدي حسب المفاتيح.

في الأخير قمنا بالبحث عن قيمة مفتاح أدخالناه سابقاً.


Main.java
                    import java.util.TreeMap;           // TreeMap هنا قمنا باستدعاء الكلاس
                    import java.util.iterator;          // iterator هنا قمنا باستدعاء الإنترفيس

                    public class Main {

                    public static void main(String[] args) {

                    // و الذي سنضع فيه كود البلد و إسمه tm إسمه TreeMap هنا قمنا بإنشاء كائن نوعه
                    TreeMap tm = new TreeMap();

                    // كل عنصر يحتوي على كود البلد كمفتاح و إسمه كقيمة . لاحظ لاحقاً أنه سيتم عرضهم بالتريتب من المفتاح الأصغر إلى المفتاح الأكبر .tm هنا قمنا بإضافة 12 عنصر في الكائن
                    tm.put("+961", "Lebanon");
                    tm.put("+962", "Jordan");
                    tm.put("+963", "Syria");
                    tm.put("+964", "Iraq");
                    tm.put("+965", "Kuwait");
                    tm.put("+966", "KSA");
                    tm.put("+967", "Yaman");
                    tm.put("+968", "Oman");
                    tm.put("+970", "Palestine");
                    tm.put("+212", "Morocco");
                    tm.put("+281", "Libya");
                    tm.put("+20",  "Egypt");

                    // أي وضعنا اكواد البلاد فيه .keys بداخل الكائن tm هنا قمنا بتخزين جميع مفاتيح الكائن
                    Iterator keys = tm.keySet().iterator();

                    // أي وضعنا أسماء البلاد فيه .values بداخل الكائن tm هنا قمنا بتخزين جميع قيم الكائن
                    Iterator values = tm.values().iterator();

                    System.out.println("The table below contains all Codes & Countries \n");
                    System.out.println("---------------------");
                    System.out.println("Code \t | Country");
                    System.out.println("---------------------");

                    // لا يزال يحتوي على مفاتيح keys هنا أنشأنا حلقة تستمر في تكرار نفسها طالما أن الكائن
                    // الفكرة هنا المرور على جميع المفاتيح الموجودة و عرض كل مفتاح موجود و قيمته
                    while( keys.hasNext() ) {
                    System.out.println(keys.next() + "\t | " + values.next());
                    }
                    System.out.println("---------------------\n");


                    // KSA هنا قمنا بالبحث عن إسم البلد الذي يملك الكود 996+ فكان الجواب
                    System.out.println("Which Country use the code +966 ?");
                    System.out.println(tm.get("+966"));

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    The table below contains all Codes & Countries

                    ---------------------
                    Code     | Country
                    ---------------------
                    +20      | Egypt
                    +212     | Morocco
                    +281     | Libya
                    +961     | Lebanon
                    +962     | Jordan
                    +963     | Syria
                    +964     | Iraq
                    +965     | Kuwait
                    +966     | KSA
                    +967     | Yaman
                    +968     | Oman
                    +970     | Palestine
                    ---------------------

                    Which Country use the code +966 ?
                    KSA
                  
__________&&&______;&&&___________;&&&&________;الإطار Collection في جافا | Java Collections

 مجموعة الخوارزميات في جافا ( Java Algorithms Collections )

مقدمة

الكلاس Collections يحتوي على دوال ثابتة نوعها static. هذه الدوال تساعد كثيراً في الوصول إلى العناصر و التلاعب بها سواء كنت تتعامل مع الكلاسات التي ترث من الإنترفيس Collections أو مع الكلاسات التي ترث من الإنترفيس Map.

إذاً هذه الدوال تغنيك عن كتابة خوارزميات صعبة و معقدة, لذلك سميت مجموعة الخوارزميات ( Algorithms Collection ).

ميزة أخرى يقدمها لك الكلاس Collections هي المزامنة ( Synchronization), ستعرف أهمية المزامنة لاحقاً في هذا الدرس.


أخطاء محتملة

  • بعض الدوال التي يملكها ترمي الإستثناء UnsupportedOperationException إذا تم استخدامهم بطريقة خاطئة.

  • يرمى الإستثناء ClassCastException في حال كان لا يمكن تحويل نوع الكائن إلى نوع آخر.


طريقة التعامل مع مجموعة الخوارزميات

للتعامل مع الدوال الموجودة في مجموعة الخوارزميات عليك إتباع الخطوات التالية:

  1. إستدعاء الكلاس Collections, أي يجب أن تفعل له import.

  2. إستدعاء أي دالة تريد منه بشكل مباشر, أي ضع الكلمة Collections تليها نقطة, تليها إسم الدالة التي تريد.

دوال الكلاس Collections

الجدول التالي يحتوي على دوال الكلاس Collections الثابتة و التي تمثل مجموعة الخوارزميات.

الدالة مع تعريفها
public static int binarySearch(List list, Object value) ترجع رقم index يمثل أول عنصر يملك القيمة value في الكائن list.
ترجع 1- في حال عدم إيجاد القيمة المطلوبة.
public static int binarySearch(List list, Object value, Comparator c) ترجع رقم index يمثل أول عنصر يملك القيمة value في الكائن list.
الكائن c يحدد الطريقة التي ستعتمدها الدالة في البحث.
ترجع 1- في حال عدم إيجاد القيمة المطلوبة.
public static void copy(List list1, List list2) تنسخ عناصر الكائن list2 في آخر الكائن list1.
public static Enumeration enumeration(Collection c) ترجع كائن نوعه Enumeration يحتوي على جميع عناصر الكائن c.
public static void fill(List list, Object obj) تضع الكائن obj كقيمة لجميع عناصر الكائن list.
public static int indexOfSubList(List list, List subList) تبحث في الكائن list عن أول مكان يحتوي على جميع عناصر الكائن subList و بنفس الترتيب فيه.
في حال وجدت جميع عناصر الكائن subList بنفس الترتيب في الكائن list, ترجع رقم يمثل index أول عنصر بدء عنده إيجاد عناصر الكائن subList في الكائن list.
ترجع 1- في حال عدم إيجاد القيمة المطلوبة.
public static int lastIndexOfSubList(List list, List subList) تبحث في الكائن list عن آخر مكان يحتوي على جميع عناصر الكائن subList و بنفس الترتيب فيه.
في حال وجدت جميع عناصر الكائن subList بنفس الترتيب في الكائن list, ترجع رقم يمثل index آخر عنصر بدء عنده إيجاد عناصر الكائن subList في الكائن list.
ترجع 1- في حال عدم إيجاد القيمة المطلوبة.
public static ArrayList list(Enumeration enum) ترجع كائن نوعه ArrayList يحتوي على جميع عناصر الكائن enum.
public static Object max(Collection c) ترجع أكبر عنصر موجود في الكائن c.
public static Object max(Collection c, Comparator comp) ترجع أكبر عنصر موجود في الكائن c.
الكائن comp يحدد الطريقة التي تعتمدها الدالة في مقارنة العناصر.
public static Object min(Collection c) ترجع أصغر عنصر موجود في الكائن c.
public static Object min(Collection c, Comparator comp) ترجع أصغر عنصر موجود في الكائن c.
الكائن comp يحدد الطريقة التي تعتمدها الدالة في مقارنة العناصر.
public static List nCopies(int num, Object obj) ترجع كائن نوعه List يحتوي على نسخ من الكائن obj.
المتغير num يمثل عدد النسخ التي سيتم إنشاءها من الكائن obj. قيمة المتغير num يجب أن تكون أكبر أو تساوي صفر.
إذاً هنا عدد عناصر الكائن list الذي ترجعه الدالة يمثل عدد عناصر الكائن obj الموجودة فيه.
public static boolean replaceAll(List list, Object oldValue, Object newValue) تبدل قيمة كل عنصر موجود في الكائن list في حال كانت تساوي قيمة الكائن oldValue بقيمة الكائن newValue.
ترجع true في حال تم تبديل قيمة عنصر واحد على الأقل, غير ذلك ترجع false.
public static void reverse(List list) تعكس ترتيب عناصر الكائن list.
public static Comparator reverseOrder() ترجع كائن نوعه Comparator يمثل الكائن المستخدم في عكس ترتيب عناصر الكائنات.
public static void rotate(List list, int n) تغير طريقة ترتيب عناصر الكائن list.
الباراميتر N يحدد كيف سيتم تبديل أماكن عناصر الكائن list.
ضع قيمة أصغر من صفر دائماً مكان الباراميتر N.
فمثلاً إذا وضعنا القيمة 2- مكان الباراميتر N, سيتم وضع آخر عنصرين موجودين في الكائن list في أوله.
public static void shuffle(List list) تقوم بتبديل أمكان عناصر الكائن list بشكل عشوائي مرة واحدة.
public static void shuffle(List list, Random rnd) تقوم بتبديل أمكان عناصر الكائن list بشكل عشوائي عدة مرات.
الكائن rnd يحدد كم مرة سيتم تبديل أماكنهم.
public static Set singleton(Object obj) ترجع نسخة من الكائن obj نوعها Set لا يمكن إجراء أي تعديل مباشر عليها لأنها تعتبر immutable.

إنتبه: هنا أي تعديل تفعله على الكائن الأصلي الذي قمت بتمريره مكان الباراميتر obj يطبق على النسخة التي أرجعتها الدالة أيضاً.
أي تعديل تحاول فعله على النسخة التي أرجعتها الدالة من هذا الكائن لا تؤثر عليها أو على الكائن الأصلي بتاتاً.
public static List singletonList(Object obj) ترجع نسخة من الكائن obj نوعها List لا يمكن إجراء أي تعديل مباشر عليها لأنها تعتبر immutable.

إنتبه: هنا أي تعديل تفعله على الكائن الأصلي الذي قمت بتمريره مكان الباراميتر obj يطبق على النسخة التي أرجعتها الدالة أيضاً.
أي تعديل تحاول فعله على النسخة التي أرجعتها الدالة من هذا الكائن لا تؤثر عليها أو على الكائن الأصلي بتاتاً.
public static Map singletonMap(Object keys, Object values) ترجع نسخة من الكائنات keys و values في كائن واحد نوعه Map لا يمكن إجراء أي تعديل مباشر عليه لأنه يعتبر immutable.
الكائن keys يمثل جميع المفاتيح التي ستحتويها النسخة Map التي سترجعها الدالة.
الكائن values يمثل جميع القيم التي ستحتويها النسخة Map التي سترجعها الدالة.

إنتبه: هنا أي تعديل تفعله على الكائنات الأصلية الذي قمت بتمريرها مكان الباراميترات keys و values يطبق على النسخة التي أرجعتها الدالة أيضاً.
أي تعديل تحاول فعله على النسخة التي أرجعتها الدالة من هذه الكائنات لا تؤثر عليها أو على الكائنات الأصلية بتاتاً.
public static void sort(List list, Comparator comp) ترتب العناصر الموجودة في الكائن list حسب طريقة المقارنة التي يعتمدها الكائن comp.
public static void sort(List list) ترتب العناصر الموجودة في الكائن list حسب طريقة المقارنة التي يعتمدها كائن الـ Comparator الذي يستخدمه الكائن list إفتراضياً.
public static void swap(List list, int index1, int index2) تبدل قيم العناصر الموجودة على الـ index1 و الـ index2.
public static Collection synchronizedCollection(Collection c) ترجع الكائن c ككائن متزامن نوعه Collections.
public static List synchronizedList(List list) ترجع الكائن list ككائن متزامن نوعه List.
public static Map synchronizedMap(Map m) ترجع الكائن m ككائن متزامن نوعه Map.
public static Set synchronizedSet(Set s) ترجع الكائن S ككائن متزامن نوعه Set.
public static SortedMap synchronizedSortedMap(SortedMap sm) ترجع الكائن sm ككائن متزامن نوعه SortedMap.
public static SortedSet synchronizedSortedSet(SortedSet ss) ترجع الكائن ss ككائن متزامن نوعه SortedSet.
public static Collection unmodifiableCollection(Collection c) ترجع الكائن c ككائن نوعه Collections غير قابل للتعديل.
public static List unmodifiableList(List list) ترجع الكائن list ككائن نوعه List غير قابل للتعديل.
public static Map unmodifiableMap(Map m) ترجع الكائن m ككائن نوعه Map غير قابل للتعديل.
public static Set unmodifiableSet(Set s) ترجع الكائن S ككائن نوعه Set غير قابل للتعديل.
public static SortedMap unmodifiableSortedMap(SortedMap sm) ترجع الكائن sm ككائن نوعه SortedMap غير قابل للتعديل.
public static SortedSet unmodifiableSortedSet(SortedSet ss) ترجع الكائن ss ككائن نوعه SortedSet غير قابل للتعديل.

المزامنة ( Synchronization )

في جميع الأمثلة التي وضعناها سابقاً لم نتطرق لفكرة المزامنة لأننا كنا نريدك أن تركز على فكرة و أهمية كل كلاس موجود ضمن كلاسات الـ Data Structure فقط.
في الحقيقة لم نضطر إلى مزامنة الكود أصلاً لأننا كنا نضع أمثلة صغيرة لا تحتوي على أوامر متزامنة, و بالتالي لا حاجة أصلاً للمزامنة.

تحتاج إلى مزامنة الكائن المستخدم في تخزين البيانات في حال كان البرنامج يحتوي على عدة أوامر تعمل بشكل متزامن, أي في حال وجود Thread آخر شغال في نفس الوقت الذي نحاول فيه المرور على عناصر الكائن.

إذاً من المهم جداً التأكد أن الكائن الذي تريد المرور على عناصره هو كائن متزامن ( Synchronized ) في حال وجود أكثر من Thread شغال في البرنامج.


ملاحظة

الكلاس Vector و الكلاس HashTable لا حاجة إلى مزامنتهم لأنهم أصلاً متزامنين.


طريقة المزامنة

المزامنة أمر سهل جداً و هي مقسمة إلى خطوتين أساسياتين:

  1. جعل الكائن متزامن مباشرةً عند إنشاءه باستخدام دالة من دوال التزامن الموجودة في الكلاس Collections تكون ملائمة لنوعه.

  2. وضع الكود الذي يمكننا من المرور على عناصر هذا الكائن في بلوك متزامن باستخدام الكلمة المحجوزة synchronized.


مثال

في المثال التالي قمنا بإنشاء كائن متزامن نوعه ArrayList, إسمه al يحتوي على 5 عناصر.
بعدها قمنا بتخزين هذه العناصر في كائن نوعه Iterator, إسمه i, ثم قمنا بعرض عناصر الكائن i بشكل متزامن بواسطة الحلقة while.

Main.java
                    import java.util.ArrayList;          // ArrayList هنا قمنا باستدعاء الكلاس
                    import java.util.Collections;        // Collections هنا قمنا باستدعاء الكلاس
                    import java.util.Iterator;           // Iterator هنا قمنا باستدعاء الإنترفيس
                    import java.util.List;               // List هنا قمنا باستدعاء الإنترفيس

                    public class Main {

                    public static void main(String[] args) {

                    // al إسمه ArrayList هنا قمنا بإنشاء كائن متزامن من الكلاس
                    List al = Collections.synchronizedList( new ArrayList() );

                    // al هنا قمنا بإضافة 5 عناصر في الكائن
                    al.add("A");
                    al.add("B");
                    al.add("C");
                    al.add("D");
                    al.add("E");

                    // متزامنة al هنا قمنا بإنشاء بلوك يجعل العمليات التي تجري على الكائن
                    synchronized( al ) {
                    // al وضعنا فيه جميع عناصر الكائن i إسمه Iterator هنا قمنا بإنشاء كائن نوعه
                    Iterator i = al.iterator();

                    // و تعرض كل عنصر تمر عليه i هنا أنشأنا حلقة تمر على جميع عناصر الكائن
                    while(i.hasNext()) {
                    System.out.println(i.next());
                    }
                    }

                    }

                    }
                  

سنحصل على النتيجة التالية عند التشغيل.

                    A
                    B
                    C
                    D
                    E
                  
مثال شامل

في المثال التالي قمنا بإنشاء كائن من الكلاس ArrayList إسمه al, ثم أدخلنا فيه خمسة عناصر.
بعدها وضعنا جميع عناصر الكائن al في كائن نوعه Iterator إسمه i.
في الأخير قمنا بإنشاء حلقة تعرض لنا جميع عناصر الكائن i.


Main.java
                    import java.util.ArrayList;          // ArrayList هنا قمنا باستدعاء الكلاس
                    import java.util.Collections;        // Collections هنا قمنا باستدعاء الكلاس
                    import java.util.Comparator;         // Comparator هنا قمنا باستدعاء الإنترفيس
                    import java.util.Random;             // Random هنا قمنا باستدعاء الكلاس

                    public class Main {

                    public static void main(String[] args) {

                    // al إسمه ArrayList هنا قمنا بإنشاء كائن من الكلاس
                    ArrayList al = new ArrayList();

                    // al هنا قمنا بإضافة 5 عناصر في الكائن
                    al.add(4);
                    al.add(9);
                    al.add(-5);
                    al.add(-2);
                    al.add(7);

                    // التي قمنا بإدخالها al هنا عرضنا عناصر الكائن
                    System.out.println("List values:             " +al );


                    // بشكل تصاعدي ثم عرضناهم al هنا قمنا بترتيب عناصر الكائن
                    Collections.sort(al);
                    System.out.println("List sorted:             " +al );


                    // بالمقلوب, و بالتالي ظهر و كأننا عرضناهم بشكل تنازلي al هنا قمنا بترتيب عناصر الكائن
                    Comparator r = Collections.reverseOrder();
                    Collections.sort(al, r);
                    System.out.println("List sorted in reverse:  " +al );


                    // مرة واحدة بشكل عشوائي ثم عرضناهم al هنا قمنا بتبديل أماكن عناصر الكائن
                    Collections.shuffle(al);
                    System.out.println("List shuffled once:      " +al );


                    // خمس مرات بشكل عشوائي ثم عرضناهم al هنا قمنا بتبديل أماكن عناصر الكائن
                    Collections.shuffle(al, new Random(5));
                    System.out.println("List shuffled 5 times:   " +al );


                    // al هنا قمنا بعرض أصغر و أكبر قيمة في الكائن
                    System.out.println("List minimum value:      " +Collections.min(al) );
                    System.out.println("List maximum value:      " +Collections.max(al) );

                    }

                    }
                  

سنحصل على نتيجة تشبه النتيجة التالية عند التشغيل لأن الدالة shuffle() تبدل أماكن العناصر بشكل عشوائي.

                    List values:             [4, 9, -5, -2, 7]
                    List sorted:             [-5, -2, 4, 7, 9]
                    List sorted in reverse:  [9, 7, 4, -2, -5]
                    List shuffled once:      [7, -2, 9, 4, -5]
                    List shuffled 5 times:   [4, -2, -5, 7, 9]
                    List minimum value:      -5
                    List maximum value:      9
                  
__________&&&______;&&&___________;&&&&________; __________&&&______;&&&___________;&&&&________;