وفقًا للاتفاقية، عند استخدام برمجة Java، يجب عليك استخدام مكتبات الفئات الموجودة قدر الإمكان. بالطبع، يمكنك أيضًا كتابة طريقة فرز أو إطار عمل بنفسك، ولكن كم عدد الأشخاص الذين يمكنهم الكتابة بشكل أفضل من أولئك الموجودين في JDK؟ فائدة أخرى لاستخدام الفئات الموجودة هي أن التعليمات البرمجية سهلة القراءة والصيانة. تتحدث هذه المقالة بشكل أساسي عن كيفية استخدام مكتبات الفئات الموجودة لفرز المصفوفات وحاويات المجموعة المتنوعة (تأتي بعض الأمثلة في المقالة من "Java Developers Almanac 1.4》". )
بادئ ذي بدء، تحتاج إلى معرفة فئتين: java.util.Arrays وjava.util.Collections (لاحظ الفرق مع المجموعة). المجموعة هي واجهة المستوى الأعلى لإطار عمل المجموعة، وتحتوي المجموعات على العديد من الأساليب الثابتة. نستخدم المصفوفات لفرز المصفوفات والمجموعات لفرز حاويات الإطارات المدمجة، مثل ArraysList وLinkedList وما إلى ذلك.
يجب إضافة java.util.* وأكواد الصدفة الأخرى، مثل الفئات والطرق الرئيسية الثابتة، إلى الأمثلة، وسأكتب جميع الأكواد في المثال الأول، وسأحذفها دون استثناء في المثال التالي.
فرز المصفوفة
على سبيل المثال، هناك مجموعة من الأعداد الصحيحة:
انسخ رمز الكود كما يلي:
int[] intArray = new int[] {4, 1, 3, -23};
كيف نقوم بفرزها؟ هل تفكر في خوارزمية الفرز السريع في هذا الوقت؟ ألق نظرة على كيفية القيام بذلك:
انسخ رمز الكود كما يلي:
import java.util.*;
فرز الطبقة العامة {
public static void main(String[] args){
int[] intArray = new int[] {4, 1, 3, -23};
Arrays.sort(intArray);
}
}
بهذه الطريقة، نستخدم الطريقة الثابتةsort() للمصفوفات لفرز intArray بترتيب تصاعدي، والآن أصبح المصفوفة {-23,1,3,4}.
إذا كانت مصفوفة أحرف:
انسخ رمز الكود كما يلي:
String[] strArray = new String[] {"z"، "a"، "C"}؛
نحن نستخدم:
انسخ رمز الكود كما يلي:
Arrays.sort(strArray);
النتيجة بعد الفرز هي {C, a, z}، وسيتم الفرز () بترتيب تصاعدي وفقًا للترتيب الطبيعي للعناصر. إذا كنت تريد أن تكون غير حساس لحالة الأحرف، يمكنك كتابة:
انسخ رمز الكود كما يلي:
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
بالطبع، يمكننا أيضًا تحديد قسم معين من المصفوفة لفرزه، على سبيل المثال، إذا أردنا فرز الأجزاء من 0 إلى 2 من المصفوفة (بافتراض أن طول المصفوفة أكبر من 3)، وتبقى الأجزاء الأخرى دون تغيير، فإننا يمكن استخدام:
انسخ رمز الكود كما يلي:
Arrays.sort(strArray,0,2);
وبهذه الطريقة، نقوم فقط بفرز العناصر الثلاثة الأولى دون التأثير على الأجزاء التالية.
بالطبع قد يفكر البعض، كيف أقوم بالفرز بترتيب تنازلي؟ من بين العديد من طرق الفرز، نسخة واحدة من التعليمات البرمجية هي كما يلي:
فرز (T[] أ، المقارنة<؟ سوبر T> ج)
يمكننا استخدام Comparator للحصول على Comparator بترتيب عكسي وسيتم شرح Comparator لاحقًا. خذ intArray[] السابق كمثال:
انسخ رمز الكود كما يلي:
Arrays.sort(intArray,Comparator.reverseOrder());
وبهذه الطريقة تكون النتيجة {4,3,1,-23}. إذا لم نرغب في تعديل الكود الأصلي فيمكننا أيضًا استخدام:
انسخ رمز الكود كما يلي:
Collections.reverse(Arrays.asList(intArray));
احصل على الترتيب العكسي للمصفوفة. والنتيجة هي أيضًا 4,3,1,-23}.
لقد تغير الوضع الآن. لم تعد مصفوفتنا مصفوفة من نوع البيانات البدائية (النوع البدائي) أو نوع السلسلة، بل مصفوفة من الكائنات. الترتيب الطبيعي لهذه المصفوفة غير معروف، لذا نحتاج إلى تنفيذ الواجهة القابلة للمقارنة لهذه الفئة، على سبيل المثال، لدينا فئة الاسم:
انسخ رمز الكود كما يلي:
يطبق اسم الفئة Comparable<Name>{
الاسم الأول للسلسلة العامة، الاسم الأخير؛
الاسم العام (الاسم الأول للسلسلة، الاسم الأخير للسلسلة) {
this.firstName=firstName;
this.lastName=lastName;
}
public int CompareTo(Name o) { // تنفيذ الواجهة
int lastCmp=lastName.compareTo(o.lastName);
return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName));
}
public String toString(){ // مناسب لاختبار الإخراج
إرجاع الاسم الأول+" "+اسم العائلة;
}
}
بهذه الطريقة، عندما نقوم بفرز مصفوفة الكائنات هذه، سنقوم أولاً بمقارنة الاسم الأخير، ثم مقارنة الاسم الأول، ثم نحصل على ترتيب الكائنين، تمامًا مثل ما تم تنفيذه في CompareTo(Name o). يمكنك أيضًا تجربة ذلك مع البرنامج:
انسخ رمز الكود كما يلي:
import java.util.*;
تصنيف اسم الفئة العامة {
public static void main(String[] args) {
اسم nameArray[] = {
الاسم الجديد ("جون"، "لينون")،
الاسم الجديد ("كارل"، "ماركس")،
الاسم الجديد ("جروشو"، "ماركس")،
الاسم الجديد ("أوسكار"، "جروش")
};
Arrays.sort(nameArray);
for(int i=0;i<nameArray.length;i++){
System.out.println(nameArray[i].toString());
}
}
}
والنتيجة كما توقعنا:
انسخ رمز الكود كما يلي:
أوسكار جروتش
جون لينون
جروتشو ماركس
كارل ماركس
فرز إطارات المجموعة
إذا كنت قد فهمت Arrays.sort() لفرز المصفوفات، فإن استخدام إطار عمل المجموعة مشابه. ما عليك سوى استبدال المصفوفات بالمجموعات. لاحظ أن المجموعات هي فئة وأن المجموعة عبارة عن واجهة. على الرغم من وجود اختلاف واحد فقط، إلا أن معانيها مختلفة تمامًا.
لنفترض أن هناك مثل هذه القائمة المرتبطة:
انسخ رمز الكود كما يلي:
LinkedList list=new LinkedList();
list.add(4);
list.add(34);
list.add(22);
list.add(2);
نحتاج فقط إلى استخدام:
انسخ رمز الكود كما يلي:
Collections.sort(list);
يمكنك فرز العناصر في ll من الصغير إلى الكبير، وتصبح النتيجة:
انسخ رمز الكود كما يلي:
[2، 4، 22، 34]
إذا كانت العناصر الموجودة في LinkedList عبارة عن سلاسل، فسيتم أيضًا فرزها من الصغيرة إلى الكبيرة مثل أنواع البيانات الأساسية.
إذا كنت تريد تنفيذ الفرز العكسي، أي من الوصول إلى الفرز الصغير:
انسخ رمز الكود كما يلي:
Collections.sort(list,Collections.reverseOrder());
إذا كانت العناصر الموجودة في LinkedList عبارة عن كائنات مخصصة، فيمكنك تنفيذ الواجهة القابلة للمقارنة مثل كائن الاسم أعلاه، ثم السماح لـ Collection.sort() بفرزها نيابةً عنك.
إذا كنت تريد فرز كائن وفقًا لأفكارك الخاصة، فيمكنك استخدام الكود المنسوخ على النحو التالي:
فرز (قائمة<T>، مقارنة<؟ سوبر T> ج)
تقوم هذه الطريقة بالفرز قبل إعطاء مثال، يجب علينا أولاً شرح استخدام المقارنة وتنسيق الواجهة القابلة للمقارنة:
انسخ رمز الكود كما يلي:
مقارنة الواجهة العامة<T> {
كثافة العمليات مقارنة (T o1، T o2)؛
}
في الواقع، طريقة كتابة int Compare(T o1,T o2) في Comparator تشبه طريقة كتابة طريقة CompareTo() في Comparable. في فئة الاسم المذكورة أعلاه، تبدأ المقارنة من LastName. هذه هي عادة الغربيين. في الصين، نريد أن نبدأ المقارنة من fristName دون تعديل الكود الأصلي. في هذا الوقت، يمكن أن يكون Comparator مفيدًا:
انسخ رمز الكود كما يلي:
المقارنة النهائية<الاسم> FIRST_NAME_ORDER=المقارنة الجديدة<الاسم>() {
مقارنة int العامة (الاسم n1، الاسم n2) {
int firstCmp=n1.firstName.compareTo(n2.firstName);
return (firstCmp!=0?firstCmp:n1.lastName.compareTo
(n2.firstName));
}
};
بهذه الطريقة، تتم كتابة المقارنة المخصصة لدينا FIRST_NAME_ORDER.
تحويل مصفوفة الأسماء في المثال السابق إلى قائمة:
انسخ رمز الكود كما يلي:
List<Name> list=Arrays.asList(nameArray);
Collections.sort(list,FIRST_NAME_ORDER);
بهذه الطريقة، نجحنا في ضبط الفرز باستخدام أداة المقارنة المحددة لدينا.