Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

compareTo() و Comparable

جزء من قسم Object Oriented Programming في رحلة Java على Coddy — الدرس 44 من 87.

تسمح واجهة Comparable للكائنات بتعريف ترتيبها الطبيعي. من خلال تنفيذ هذه الواجهة، يمكن فرز فئتك (class) تلقائيًا باستخدام طرق مثل Collections.sort() أو تخزينها في مجموعات مرتبة مثل TreeSet.

تتطلب الواجهة منك تنفيذ طريقة واحدة: compareTo(). تقوم هذه الطريقة بمقارنة الكائن الحالي بكائن آخر وتعيد عدداً صحيحاً يشير إلى ترتيبهما النسبي:

  • قيمة سالبة: يأتي هذا الكائن قبل الآخر
  • صفر: كلا الكائنين متساويان
  • قيمة موجبة: يأتي هذا الكائن بعد الآخر
public class Person implements Comparable<Person> {
    private String name;
    private int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public int compareTo(Person other) {
        return this.age - other.age;  // الترتيب حسب العمر تصاعدياً
    }
}

بمجرد التنفيذ، يصبح الفرز بسيطاً:

List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
Collections.sort(people);  // مرتبة الآن حسب العمر: Bob, Alice

لمقارنة السلاسل النصية أو غيرها من الحقول التي تدعم Comparable، يمكنك التفويض إلى طريقة compareTo() الخاصة بها بدلاً من استخدام الطرح: return this.name.compareTo(other.name);. هذا النهج أكثر أماناً ويتعامل مع الحالات الاستثنائية بشكل صحيح.

challenge icon

التحدي

سهل

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

ستقوم بتنظيم الكود الخاص بك عبر ملفين:

  • Movie.java: قم بإنشاء فئة تمثل فيلماً يمكن مقارنته بالأفلام الأخرى. يحتوي الفيلم على ثلاثة حقول خاصة: title (String)، و director (String)، و rating (double، من 0.0 إلى 10.0). قم بتضمين منشئ (constructor) لتهيئة جميع الحقول وطرق جلب (getter methods) لكل منها.

    اجعل فئة Movie الخاصة بك تنفذ Comparable<Movie> وقم بتجاوز طريقة compareTo(). يجب فرز الأفلام حسب التقييم في ترتيب تنازلي (الأعلى تقييماً أولاً). عند مقارنة القيم من نوع double، استخدم Double.compare() لإجراء مقارنة آمنة — تذكر عكس الترتيب للفرز التنازلي!

    قم بتجاوز toString() لترجع: [title] by [director] - Rating: [rating]

  • Main.java: ابعث الحياة في فئة Movie الخاصة بك عن طريق إنشاء قائمة من الأفلام وفرزها. ستتلقى مدخلات لثلاثة أفلام، كل منها في سطر منفصل بالتنسيق التالي: title,director,rating

    قم بتحليل كل سطر لإنشاء كائنات Movie، وأضفها إلى ArrayList، ثم استخدم Collections.sort() لفرز القائمة. بفضل تنفيذك لواجهة Comparable، ستترتب الأفلام تلقائياً حسب التقييم!

    بعد الفرز، اطبع كل فيلم في سطر خاص به باستخدام تنسيق toString(). يجب أن يظهر الفيلم الأعلى تقييماً أولاً.

ستتلقى ثلاثة أسطر من المدخلات، يحتوي كل منها على بيانات الفيلم بالتنسيق: title,director,rating

على سبيل المثال، قد يبدو سطر الإدخال كما يلي: Inception,Christopher Nolan,8.8

تذكر استيراد java.util.ArrayList و java.util.Collections و java.util.Scanner في ملف Main الخاص بك. لاحظ كيف يتيح لك تنفيذ Comparable فرز كائناتك المخصصة باستدعاء طريقة واحدة فقط — دون الحاجة إلى مقارن (comparator) إضافي!

ورقة مرجعية

تسمح واجهة Comparable للكائنات بتعريف ترتيبها الطبيعي للفرز التلقائي.

قم بتنفيذ طريقة compareTo() التي تُرجع:

  • قيمة سالبة: هذا الكائن يأتي قبل الآخر
  • صفر: كلا الكائنين متساويان
  • قيمة موجبة: هذا الكائن يأتي بعد الآخر
public class Person implements Comparable<Person> {
    private int age;
    
    @Override
    public int compareTo(Person other) {
        return this.age - other.age;  // فرز حسب العمر تصاعدياً
    }
}

قم بفرز الكائنات باستخدام Collections.sort():

List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
Collections.sort(people);  // تم الفرز حسب العمر

لمقارنة السلاسل النصية، قم بالتفويض إلى طريقة compareTo() الخاصة بها:

return this.name.compareTo(other.name);

لمقارنة القيم من نوع double بأمان، استخدم Double.compare():

return Double.compare(this.rating, other.rating);  // تصاعدي
return Double.compare(other.rating, this.rating);  // تنازلي

جرّب بنفسك

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // قراءة ثلاثة أسطر من بيانات الأفلام
        String line1 = scanner.nextLine();
        String line2 = scanner.nextLine();
        String line3 = scanner.nextLine();
        
        // TODO: إنشاء ArrayList لتخزين كائنات Movie
        
        // TODO: تحليل كل سطر (التنسيق: title,director,rating)
        // Hint: استخدم split(",") لفصل الأجزاء
        // Hint: استخدم Double.parseDouble() من أجل rating
        
        // TODO: إنشاء كائنات Movie وإضافتها إلى القائمة
        
        // TODO: فرز القائمة باستخدام Collections.sort()
        
        // TODO: طباعة كل فيلم (واحد في كل سطر)
    }
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming