مقدمة
عندما يشير إلى تشغيل المقارنة لمقارنة "حجم" كائنين عند إجراء خوارزميات مثل نوع الإدراج وفرز التل ودمج الفرز. من السهل فهم طريقة المقارنة لـ Integer I> J ، ولكن عندما نفرز كائنات متعددة ، كيف نقارن "حجم" كائنين؟ من الواضح أن مقارنات STU1> STU2 من المستحيل تجميعها. لحل مشكلة كيفية مقارنة حجم كائنين ، يوفر JDK واجهتين java.lang.Comparable و java.util.Comparator .
1. الفرز الطبيعي: java.lang.comparable
لا يوجد سوى طريقة واحدة متوفرة في الواجهة المماثلة: compareTo(Object obj) ، وقيمة إرجاع هذه الطريقة هي int. إذا كانت قيمة الإرجاع رقمًا موجبًا ، فهذا يعني أن الكائن الحالي (الكائن الذي يدعو الطريقة) "أكبر" من كائن OBJ ؛ خلاف ذلك ، فهو "صغير" ؛ إذا كان الصفر ، فهذا يعني أن الكائنين متساوين.
فيما يلي فصل طالب ينفذ الواجهة المماثلة:
طالب الطبقة العامة ينفذ قابلة للمقارنة {private int id ؛ اسم السلسلة الخاصة ؛ الطالب العام () {super () ؛ } Override public int compareto (Object obj) {if (obj extureof student) {student stu = (student) obj ؛ معرف الإرجاع - stu.id ؛ } العودة 0 ؛ } Override Public String ToString () {return "<" + id + "،" + name + ">" ؛ }} الطالب ينفذ واجهة الفرز الطبيعية مماثلة. فكيف نستخدم هذه الواجهة لفرز مجموعة من كائنات الطلاب؟ عندما كنا نتعلم صفائف ، استخدمنا فصلًا لفرز صفائف عدد صحيح: java.util.Arrays . نستخدم طريقة فرز المصفوفات لفرز صفائف عدد صحيح. بعد التقليب من خلال وثائق API ، ستجد أن المصفوفات تعطي العديد من الأشكال المحملة من طريقة الفرز ، بما في ذلك sort(Object[] obj) ، مما يعني أن ARRYA يمكن أيضًا فرز صفائف الكائنات. عند مقارنة "حجم" الكائنين أثناء عملية الفرز ، يتم استخدام الواجهة المماثلة لمقارنة طريقة المقارنة.
مقارنة الفئة العامة {public static void main (string [] args) {student stu1 = new student (1 ، "Little") ؛ الطالب STU2 = طالب جديد (2 ، "cyntin") ؛ الطالب STU3 = طالب جديد (3 ، "توني") ؛ الطالب STU4 = طالب جديد (4 ، "Gemini") ؛ الطالب [] stus = طالب جديد [4] ؛ STU0] = STU1 ؛ STU1 [1] = STU4 ؛ Stus [2] = STU3 ؛ STU3] = STU2 ؛ System.out.println ("Array:" + Arrays.ToString (Stus)) ؛ المصفوفات. System.out.println ("sort:" + arrays.toString (Stus)) ؛ }} لا تتم إضافة الترتيب الذي تتم إضافة العناصر في صفيف الطلاب وفقًا لمعرف الطالب. بعد استدعاء Arrays.sort(stus) . بغض النظر عن خوارزمية الفرز التي يتم استخدامها لتنفيذها ، فمن الضروري بالتأكيد مقارنة تشغيل "الحجم" لكائنين. فكيف تقارن "حجم" كائنين؟ الواجهة المماثلة التي تنفذها الطالب تأتي حيز التنفيذ. سيتم إلقاء طريقة الفرز الكائن ليتم مقارنته بمقارنة واتصال طريقة المقارنة للحكم على "حجم" هذين الكائنين بناءً على قيمة الإرجاع. لذلك ، في هذا المثال ، تصبح مجموعة الطالب الأصلي خارج الترتيب مصفوفة طالب مرتبة حسب رقم الطالب.
لكننا لاحظنا أن خوارزمية الفرز مرتبطة بصف الطلاب ، والطالب لديه خوارزمية فرز واحدة فقط. ولكن هذا ليس هو الحال في المجتمع الحقيقي. ماذا لو لم نرغب في الفرز حسب رقم الطالب؟ ماذا لو أردنا فرز الطلاب بالاسم؟ يمكننا فقط تعديل طريقة المقارنة للواجهة المماثلة لفئة الطالب وتغييرها للفرز حسب الاسم. ماذا لو كان هناك عمليتان في نفس النظام ، يتم فرز أحدهما حسب رقم الطالب ويتم فرز الآخر بالاسم؟ من المستحيل كتابة تطبيقتين للمقارنة في هيئة فئة الطلاب. من وجهة النظر هذه ، لها قيود قابلة للمقارنة. من أجل تعويض هذا القصور ، يوفر لنا JDK أيضًا طريقة فرز أخرى ، وهي فرز المقارنة الذي سنتحدث عنه أدناه.
2. فرز المقارنة: java.util.comparator
لقد ذكرت أعلاه أن السبب في توفير واجهة فرز المقارنة هو أنه في بعض الأحيان يكون من الضروري فرز نفس الكائن بعدة طرق مختلفة ، ولا يمكن تنفيذ هذا الفرز الطبيعي المماثل. بالإضافة إلى ذلك ، تتمثل إحدى ميزة واجهة المقارنة في أنها تفصل خوارزمية فرز المقارنة عن فئة الكيان المحددة.
إذا نظرت من خلال واجهة برمجة التطبيقات ، فستجد أن هناك أيضًا نموذجًا محملاً من المصفوفات sort(T[] a, Comparator<? super T> c) تستخدم الطريقة الأدوية العامة لكتابة معلمات هذه الطريقة ، والتي لم نذكرها بعد. يمكننا أن نفهمه على أنه هذا النموذج: sort(Object[] a, Comparator c) ، مما يعني فرز صفيف الكائن وفقًا لخوارزمية فرز المقارنة المعطاة بواسطة المقارنة ج. هناك طريقتان محددة في واجهة المقارنة: compare(Object o1, Object o2) والطرق equals . نظرًا لأن طريقة equals تحتوي على طرق لجميع الكائنات ، عندما ننفذ واجهة المقارنة ، نحتاج فقط إلى تجاوز طريقة compare ، بدلاً من تجاوز طريقة equals . إن وصف طريقة تجاوز المساواة في واجهة المقارنة هو: "لاحظ أنه من الآمن دائمًا عدم تجاوز Object.equals(Object) . نحتاج فقط إلى معرفة الجملة الأولى وهو على ما يرام. وهذا يعني ، لا يتعين علينا التفكير في كيفية تنفيذ طريقة متساوٍ ، لأنه حتى لو لم نعرض تنفيذ طريقة متساوٍ ، ولكن نستخدم طريقة متساوية في فئة الكائن ، فإن الكود لا يزال آمنًا.
لذلك دعونا نكتب رمزًا لفرزه بمقارنة. لا يزال يتم مع فصل الطالب ، ولكن لم يتم تنفيذ الواجهة المماثلة. نظرًا لأن فئة تنفيذ المقارنة تستخدم فقط العرض لتنفيذ طريقة واحدة ، لا يمكننا أن نحتاج إلى كتابة فصل لتنفيذها. عندما نحتاج إلى استخدام المقارنة ، يمكننا كتابة فئة داخلية مجهولة لتنفيذ المقارنة.
هذه هي طريقتنا للفرز بالاسم:
public void sortbyname () {student stu1 = new student (1 ، "little") ؛ الطالب STU2 = طالب جديد (2 ، "cyntin") ؛ الطالب STU3 = طالب جديد (3 ، "توني") ؛ الطالب STU4 = طالب جديد (4 ، "Gemini") ؛ الطالب [] stus = طالب جديد [4] ؛ STU0] = STU1 ؛ STU1 ؛ STU4 ؛ STU2] = STU3 ؛ STU3] = STU2 ؛ System.out.println ("Array:" + Arrays.ToString (Stus)) ؛ Arrays.sort (stus ، new Comparator () {Override public int compare (Object O1 ، Object O2) {if (O1 eastyof student && o2 eastyof student) {student s1 = (student) o1 ؛ student s2 = (student) o2 ؛ S1.GetName (). المقارنة (S2.GetName ()) ؛ system.out.println ("sorted:" + arrays.toString (stus)) ؛ }عندما نحتاج إلى فرز الطالب حسب رقم الطالب ، نحتاج فقط إلى تعديل الكود في الفصل الداخلي الذي يطرح المقارنة في طريقة الفرز الخاصة بنا ، دون تعديل فصل الطالب.
ملاحظة: بالطبع ، يمكنك أيضًا استخدام فئة الطالب لتنفيذ واجهة المقارنة ، بحيث يكون الطالب (هو) المقارنة (المقارنة). عندما تحتاج إلى استخدام هذا النوع ، ما عليك سوى استخدام الطالب كمقارنة. يمكنك تمرير الطالب كمعلمة في طريقة الفرز لأن الطالب هو مقارن. لكن مثل هذا الرمز ليس رمزًا ممتازًا ، لأن أحد الأسباب المهمة التي تجعلنا نستخدم المقارنة هو أنه يمكنه فصل خوارزمية المقارنة عن فئات محددة وتقليل الاقتران بين الفئات.
توفر Treeset الدعم لكلا طرق المقارنة ، المقابلة لطريقتي مُنشئات Treeset:
1. Treeset (): المقارنة والفرز وفقًا لطريقة المقارنة للواجهة المماثلة التي تنفذها عناصر في الأشجار
2. Treeset (مقارنة المقارنة): عناصر المقارنة والفرز في Treeset وفقًا لمقارنة المقارنة المعطاة
عند إضافة عنصر إلى Treeset ، تقوم Treeset بفرز العناصر. أما إذا كان يجب فرزه بالترتيب الطبيعي أو المقارنة ، فهذا يعتمد على كيفية كتابة بناء الأشجار. بالطبع ، لن تكون هناك مقارنة عند إضافة العنصر الأول. لا توجد عناصر في Treeset. من يمكنني المقارنة مع؟
أدناه ، يتم إعطاء رمز اختبار Treeset باستخدام طريقتين للفرز والمقارنة:
/ *** استخدم الطالب الطبيعي* يجب على الطالب تنفيذ الواجهة المماثلة ، وإلا سيتم طرح classcastexception*/ public void testSortedSet3 () {Student Stu1 = New Student (1 ، "Little") ؛ الطالب STU2 = طالب جديد (2 ، "cyntin") ؛ الطالب STU3 = طالب جديد (3 ، "توني") ؛ الطالب STU4 = طالب جديد (4 ، "Gemini") ؛ مجموعة sortedset = new Treeset () ؛ set.add (STU1) ؛ set.add (STU3) ؛ // إذا كان الطالب لا ينفذ الواجهة المماثلة ، فقم بإلقاء classcastexception set.add (STU4) ؛ set.add (STU2) ؛ set.add (STU4) ؛ set.add (طالب جديد (12 ، "ليتل")) ؛ system.out.println (set) ؛ } / *** استخدم المقارنة مع Sort* Student يمكن أن يكون مجرد فئة Java بسيطة دون تنفيذ الواجهة المماثلة*/ public void testSortedSet3 () {Student Stu1 = New Student (1 ، "Little") ؛ الطالب STU2 = طالب جديد (2 ، "cyntin") ؛ الطالب STU3 = طالب جديد (3 ، "توني") ؛ الطالب STU4 = طالب جديد (4 ، "Gemini") ؛ SoredSet Set = New Treeset (New Comparator () {Override Public int (الكائن O1 ، الكائن O2) {if (O1 eastyof student && o2 extrealof) {student s1 = (student) o1 ؛ student s2 = (student) o2 ؛ return s1.getname (). compareto (s2.getname () ؛} set.add (STU1) ؛ set.add (STU3) ؛ set.add (STU4) ؛ set.add (STU2) ؛ set.add (STU4) ؛ set.add (طالب جديد (12 ، "ليتل")) ؛ system.out.println (set) ؛ } بالإضافة إلى ذلك ، قدم فئة الأدوات ، java.util.Collections . لاحظ أن هذه ليست واجهة جمع. المجموعات تشبه إلى حد كبير فئة المصفوفات. يوفر المصفوفات سلسلة من الطرق الثابتة لعمليات الصفيف ، والعثور على الفرز ، والمزيد. توفر المجموعات أيضًا سلسلة من هذه الطرق ، ولكن يتم استخدامها لمعالجة المجموعات. على الرغم من أن فئة المجموعات تشبه إلى حد كبير واجهة المجموعات ، لا تنخدع باسم المجموعات. إنها ليست فئة تنفيذ يمكنها فقط التعامل مع واجهة التجميع ومساحات الفرعية ، ولكن يمكنها أيضًا التعامل مع فئة تنفيذ واجهة الخريطة.
لخص
هذه هي نهاية مقدمة الفرز الطبيعي وفرز المقارنة في جافا. المقالة لا تزال مفصلة نسبيا. آمل أن يساعدك في دراستك أو عملك. إذا كان لديك أي أسئلة ، فيمكنك ترك رسالة للتواصل.