0Pricing
Java Academy · درس

الفرز باستخدام Comparator وLambda

أنشئ مثيلات Comparator باستخدام تعبيرات lambda وأساليب المصنع Comparator.comparing

الفرز باستخدام Comparator وLambda درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.

الفرز باستخدام Comparator وLambda

يحدد Comparator<T> ترتيبًا خارجيًا للكائنات. وعلى خلاف Comparable، يمكنك إنشاء العدد الذي تحتاج إليه من Comparators دون تعديل الفئة.

إنشاء Comparators

أنشئ Comparator باستخدام lambda أو مرجع أسلوب، ثم مرّره إلى أساليب الفرز.

import java.util.*;

record Product(String name, double price, int stock) {}

List<Product> products = new ArrayList<>(List.of(
    new Product("Mouse",    29.99, 50),
    new Product("Laptop",  999.00, 5),
    new Product("USB Hub",  24.99, 100)
));

// Lambda comparator
products.sort((a, b) -> Double.compare(a.price(), b.price()));
System.out.println(products);
// [USB Hub, Mouse, Laptop] (by price ascending)

مصنع Comparator.comparing

تنشئ Comparator.comparing(keyExtractor) Comparator من دالة استخراج مفتاح، وهي أوضح من استخدام lambdas مباشرةً.

import java.util.Comparator;

Comparator<Product> byPrice = Comparator.comparingDouble(Product::price);
Comparator<Product> byName  = Comparator.comparing(Product::name);
Comparator<Product> byStock = Comparator.comparingInt(Product::stock);

products.sort(byPrice);
System.out.println(products); // sorted by price ascending

products.sort(byName);
System.out.println(products); // sorted alphabetically

reversed()

تعكس reversed() ترتيب أي Comparator.

import java.util.Comparator;

Comparator<Product> mostExpensiveFirst =
    Comparator.comparingDouble(Product::price).reversed();

products.sort(mostExpensiveFirst);
System.out.println(products);
// [Laptop($999.0), Mouse($29.99), USB Hub($24.99)]

naturalOrder وreverseOrder

تستخدم Comparator.naturalOrder() واجهة Comparable الخاصة بالفئة. بينما تعكس reverseOrder() ترتيبها.

List<String> names = new ArrayList<>(List.of("Charlie", "Alice", "Bob"));

names.sort(Comparator.naturalOrder());
System.out.println(names); // [Alice, Bob, Charlie]

names.sort(Comparator.reverseOrder());
System.out.println(names); // [Charlie, Bob, Alice]

// Sort integers descending
List<Integer> nums = new ArrayList<>(List.of(5, 2, 8, 1, 9));
nums.sort(Comparator.reverseOrder());
System.out.println(nums); // [9, 8, 5, 2, 1]

Comparators آمنة مع null

تتعامل Comparator.nullsFirst() وnullsLast() مع العناصر null دون NPE.

import java.util.*;

List<String> withNulls = new ArrayList<>(Arrays.asList("Charlie", null, "Alice", null, "Bob"));

withNulls.sort(Comparator.nullsLast(Comparator.naturalOrder()));
System.out.println(withNulls); // [Alice, Bob, Charlie, null, null]

withNulls.sort(Comparator.nullsFirst(Comparator.naturalOrder()));
System.out.println(withNulls); // [null, null, Alice, Bob, Charlie]

Stream sorted() مع Comparator

استخدم عملية التدفق الوسيطة sorted() مع Comparator للفرز بأسلوب برمجي وظيفي.

import java.util.stream.*;

record Employee(String name, String dept, double salary) {}

List<Employee> employees = List.of(
    new Employee("Alice",   "Engineering", 95000),
    new Employee("Bob",     "Marketing",   72000),
    new Employee("Charlie", "Engineering", 105000)
);

// Sort by salary descending in a stream pipeline
employees.stream()
    .sorted(Comparator.comparingDouble(Employee::salary).reversed())
    .forEach(e -> System.out.println(e.name() + ": $" + e.salary()));
// Charlie: $105000.0 / Alice: $95000.0 / Bob: $72000.0

Comparator كـ Lambda مقابل مرجع أسلوب

تجعل مراجع الأساليب Comparators أكثر اختصارًا عندما يكون مستخرج المفتاح عبارة عن getter بسيط.

// Lambda
Comparator<String> c1 = (a, b) -> a.length() - b.length();

// Comparator.comparing with lambda
Comparator<String> c2 = Comparator.comparing(s -> s.length());

// Comparator.comparingInt with method reference (cleanest)
Comparator<String> c3 = Comparator.comparingInt(String::length);

List<String> words = new ArrayList<>(List.of("banana", "fig", "apple", "kiwi"));
words.sort(c3);
System.out.println(words); // [fig, kiwi, apple, banana]

Comparator ذو حالة

على الرغم من أن Comparators يُفترض أن تكون بلا حالة عادةً، يمكنك تمرير الإعدادات عبر معاملات المُنشئ.

class DistanceComparator implements Comparator<String> {
    private final String target;
    DistanceComparator(String target) { this.target = target; }

    @Override
    public int compare(String a, String b) {
        return Integer.compare(distance(a), distance(b));
    }

    private int distance(String s) { return Math.abs(s.length() - target.length()); }
}

List<String> words = new ArrayList<>(List.of("Java", "Go", "Python", "C", "Kotlin"));
words.sort(new DistanceComparator("Java"));
System.out.println(words); // closest length to "Java" first

فرز مخصص لفهرس المنتجات

فرز فهرس المنتجات حسب التوفر أولًا، ثم السعر، ثم الاسم.

import java.util.*;

record Item(String name, double price, boolean inStock) {}

List<Item> catalog = List.of(
    new Item("Laptop",  999.0,  true),
    new Item("Case",     19.99, false),
    new Item("Mouse",    29.99, true),
    new Item("Monitor", 349.0,  true)
);

Comparator<Item> catalogSort =
    Comparator.comparing(Item::inStock).reversed()     // in-stock first
    .thenComparingDouble(Item::price)                  // then cheapest
    .thenComparing(Item::name);                        // then alphabetical

catalog.stream().sorted(catalogSort)
    .forEach(i -> System.out.printf("%s %-15s $%.2f%n",
        i.inStock() ? "[Y]" : "[N]", i.name(), i.price()));

Arrays.sort مع Comparator

تفرز Arrays.sort(array, comparator) مصفوفات الكائنات باستخدام Comparator مخصص.

String[] words = {"banana", "fig", "apple", "kiwi", "cherry"};

// Sort by length, then alphabetically for same length
Arrays.sort(words,
    Comparator.comparingInt(String::length)
              .thenComparing(Comparator.naturalOrder()));

System.out.println(Arrays.toString(words));
// [fig, kiwi, apple, banana, cherry]

تحقق سريع

ماذا ينتج عن Comparator.comparingDouble(Product::price).reversed()؟

مراجعة: الفرز باستخدام Comparator وLambda

أهم النقاط:

  • يحدد Comparator<T> ترتيبًا خارجيًا — استخدم العدد الذي تحتاج إليه
  • تنشئ Comparator.comparing(keyExtractor) مقارنات من دوال getter
  • تعكس reversed() أي Comparator، بينما تُستخدم naturalOrder()/reverseOrder() مع أنواع Comparable
  • تتعامل nullsFirst() وnullsLast() مع العناصر null بأمان
  • استخدم sorted(comparator) في مسارات Stream للترتيب بأسلوب وظيفي
  • يمكن تمرير Comparators إلى sort() وArrays.sort() وTreeSet وTreeMap

الأسئلة الشائعة

هل درس «الفرز باستخدام Comparator وLambda» مجاني؟

نعم — نص درس «الفرز باستخدام Comparator وLambda» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.

ماذا ستتعلم في «الفرز باستخدام Comparator وLambda»؟

أنشئ مثيلات Comparator باستخدام تعبيرات lambda وأساليب المصنع Comparator.comparing تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟

لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «الفرز باستخدام Comparator وLambda»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟

نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. واجهة Comparable
  2. الفرز باستخدام Comparator وLambda
  3. الفرز متعدد المفاتيح باستخدام thenComparing
  4. فرز المصفوفات والمجموعات عمليًا
← العودة إلى Java Academy