الكلية الجامعية للعلوم التطبيقيةبرمجة 1
English
المحاضرة 8 · 100 دقيقة

القرارات المتعددة

ماذا يفعل البرنامج حين يكون للسؤال أكثر من جوابين؟

في نهاية هذه المحاضرة ستكون قادرًا على

  1. تكتب سلسلة else-if، وترتب شروطها ترتيبًا صحيحًا
  2. تستخدم الشروط المتداخلة، وتحدد if الذي يتبعه كل else
  3. تكتب switch مع int وchar وString، وتتحكم في break وdefault
  4. تختار بين if وswitch والعامل الثلاثي بحسب المسألة
  5. تبني برامج كاملة: حاسبة بقائمة، وأيام الشهر، والسنة الكبيسة، والصرّاف الآلي
محتويات المحاضرة
  1. كثير من الأسئلة لها أكثر من جوابين
  2. تُنفِّذ السلسلة أول فرع شرطه صحيح، ثم تتجاوز الباقي
  3. ترتيب الشروط يغيّر النتيجة: ابدأ بالأضيق
  4. كلمة else هي التي تربط الشروط في سلسلة واحدة
  5. الفرع else الأخير يضمن أن يأخذ المتغير قيمة
  6. يطرح الشرط المتداخل سؤالًا بعد نجاح سؤال قبله
  7. يتبع else أقرب if مفتوح قبله، مهما كانت الإزاحة
  8. السنة الكبيسة: قاعدة واحدة تجمع ثلاثة شروط
  9. الأمر switch يقفز إلى الحالة التي تساوي القيمة
  10. دون break يكمل البرنامج إلى الحالات التالية
  11. السقوط المقصود يجمع عدة حالات في جواب واحد
  12. يعمل switch أيضًا مع char وString
  13. استخدم switch للقيم المحددة، وif لما عداها
  14. العامل الثلاثي يختار بين قيمتين في تعبير واحد
  15. التمرين النهائي: حاسبة بقائمة تجمع كل ما تعلمناه
  16. أسئلة المراجعة
الجزء الأول: سلاسل else-if

كثير من الأسئلة لها أكثر من جوابين

يختار if-else بين طريقين فقط. لكن العلامة قد تعني A أو B أو C أو D أو F، وزر المصعد قد يعني أي طابق.

سلسلة else-if

أسئلة متتالية عن مجالات من القيم: هل العلامة 90 فأكثر؟ وإلا فهل هي 80 فأكثر؟

الشرط المتداخل

سؤال داخل سؤال: هل الرمز صحيح؟ إذا كان صحيحًا، فهل الرصيد كافٍ؟

switch

سؤال واحد له قيم محددة: أي خيار ضغطت من القائمة؟

تُنفِّذ السلسلة أول فرع شرطه صحيح، ثم تتجاوز الباقي

ثلاثة أجوبة بشرطين

اضغط «تتبّع سطرًا سطرًا» وشاهد الشروط تُفحص من الأعلى. ثم جرّب n = 5 وn = 0. لماذا لا يحتاج else الأخير إلى شرط؟

public class Sign {
    public static void main(String[] args) {
        int n = -4;
        if (n > 0) {
            System.out.println("Positive");
        } else if (n < 0) {
            System.out.println("Negative");
        } else {
            System.out.println("Zero");
        }
    }
}
الناتج
Negative

درجة الحرارة 25. أكثر من شرط صحيح، فماذا يطبع البرنامج؟

public class Weather {
    public static void main(String[] args) {
        int temp = 25;
        if (temp > 30) {
            System.out.println("Hot");
        } else if (temp > 20) {
            System.out.println("Warm");
        } else if (temp > 10) {
            System.out.println("Mild");
        } else {
            System.out.println("Cold");
        }
    }
}
أظهر الناتج
الناتج
Warm

لماذا؟ temp > 10 صحيح أيضًا، لكنه لا يُفحص أصلًا. فور أن وجدت السلسلة شرطًا صحيحًا، نفّذت فرعه وخرجت.

حاسبة التقدير

أدخل 85 ثم 90 ثم 89. لاحظ أن الشرط الثاني لا يحتاج إلى mark < 90: فلو كانت العلامة 90 فأكثر لما وصل البرنامج إليه أصلًا.

import java.util.Scanner;

public class GradeChain {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Mark: ");
        int mark = input.nextInt();
        if (mark >= 90) {
            System.out.println("A");
        } else if (mark >= 80) {
            System.out.println("B");
        } else if (mark >= 70) {
            System.out.println("C");
        } else if (mark >= 60) {
            System.out.println("D");
        } else {
            System.out.println("F");
        }
    }
}

ترتيب الشروط يغيّر النتيجة: ابدأ بالأضيق

علامة ممتازة، 95، لكن الشروط بالترتيب المعكوس. ماذا يطبع؟

public class WrongOrder {
    public static void main(String[] args) {
        int mark = 95;
        if (mark >= 60) {
            System.out.println("D");
        } else if (mark >= 70) {
            System.out.println("C");
        } else if (mark >= 80) {
            System.out.println("B");
        } else if (mark >= 90) {
            System.out.println("A");
        } else {
            System.out.println("F");
        }
    }
}
أظهر الناتج
الناتج
D

لماذا؟ 95 أكبر من 60، فالشرط الأول صحيح وتنتهي السلسلة. ولن يصل البرنامج إلى A أبدًا مهما كانت العلامة: فكل علامة 90 فأكثر تتوقف عند الشرط الأول. والمترجم لا يكتشف هذا، لأنه خطأ في المنطق وليس في الكتابة.

حاسبة التقدير الصحيحة

اقرأ علامة صحيحة من 0 إلى 100، ثم اطبع التقدير: A من 90 فأكثر، وB من 80، وC من 70، وD من 60، وF لما دون ذلك. لا تطبع أي رسالة تطلب الإدخال.

import java.util.Scanner;

public class GradeCalculator {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        // Read the mark, then write the chain from highest to lowest

    }
}
stdin
100
الناتج المتوقع
A
تلميح 1

ابدأ بالشرط mark >= 90، ثم انزل تدريجيًا.

تلميح 2

الفرع الأخير else بلا شرط، وهو يطبع F.

الحل
import java.util.Scanner;

public class GradeCalculator {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int mark = input.nextInt();
        if (mark >= 90) {
            System.out.println("A");
        } else if (mark >= 80) {
            System.out.println("B");
        } else if (mark >= 70) {
            System.out.println("C");
        } else if (mark >= 60) {
            System.out.println("D");
        } else {
            System.out.println("F");
        }
    }
}

كلمة else هي التي تربط الشروط في سلسلة واحدة

حذفنا كلمة else من بين الأوامر. ماذا يطبع البرنامج؟

public class SeparateIfs {
    public static void main(String[] args) {
        int mark = 85;
        if (mark >= 90) {
            System.out.println("A");
        }
        if (mark >= 80) {
            System.out.println("B");
        }
        if (mark >= 70) {
            System.out.println("C");
        } else {
            System.out.println("F");
        }
    }
}
أظهر الناتج
الناتج
B
C

لماذا؟ هذه ثلاثة قرارات مستقلة، يُفحص كل منها بلا اعتبار لما قبله. وelse الأخير يتبع if الذي قبله مباشرة فقط، وليس الشروط كلها.

متى تستخدم عدة أوامر if منفصلة بدلًا من سلسلة؟

الفرع else الأخير يضمن أن يأخذ المتغير قيمة

المترجم لا يقرأ المنطق

نعرف نحن أن أحد الشرطين صحيح دائمًا، لكن المترجم لا يعرف. غيّر الفرع الأخير ليطمئن.

public class Result {
    public static void main(String[] args) {
        int mark = 70;
        String result;
        if (mark >= 60) {
            result = "Pass";
        } else if (mark < 60) {
            result = "Fail";
        }
        System.out.println(result);
    }
}
رسالة المترجمmight not have been initialized
أظهر التصحيح
public class Result {
    public static void main(String[] args) {
        int mark = 70;
        String result;
        if (mark >= 60) {
            result = "Pass";
        } else {
            result = "Fail";
        }
        System.out.println(result);
    }
}
الناتج
Pass

لماذا؟ لا يفحص المترجم معنى الشرطين، فيرى طريقًا محتملًا لا تتلقى فيه result أي قيمة. أما else فيغطي كل ما تبقى، فلا يبقى طريق بلا إسناد.

الجزء الثاني: الشروط المتداخلة

يطرح الشرط المتداخل سؤالًا بعد نجاح سؤال قبله

الصرّاف: الرمز أولًا ثم الرصيد

اضغط «تتبّع سطرًا سطرًا». ثم غيّر pin إلى 1111، ثم أعده وغيّر amount إلى 500. لكل جواب خطأ رسالته الخاصة، وهذا ما لا يتيحه شرط واحد مع &&.

public class NestedAtm {
    public static void main(String[] args) {
        int pin = 1234;
        int balance = 300;
        int amount = 100;
        if (pin == 1234) {
            if (amount <= balance) {
                balance -= amount;
                System.out.println("Take your cash");
                System.out.println("Balance: " + balance);
            } else {
                System.out.println("Not enough balance");
            }
        } else {
            System.out.println("Wrong code");
        }
    }
}
الناتج
Take your cash
Balance: 200

خصم يعتمد على سؤالين

المشتريات 120 والزبون عضو. جرّب تغيير المدخلات إلى 50 وno، ثم إلى 100 وno. لاحظ printf لطباعة المبلغ بمنزلتين عشريتين.

import java.util.Scanner;

public class Discount {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        double total = input.nextDouble();
        String member = input.next();
        double rate;
        if (total >= 100) {
            if (member.equals("yes")) {
                rate = 0.20;
            } else {
                rate = 0.10;
            }
        } else {
            if (member.equals("yes")) {
                rate = 0.05;
            } else {
                rate = 0.0;
            }
        }
        System.out.printf("Pay: %.2f%n", total - total * rate);
    }
}
الناتج
Pay: 96.00

سحب من الصرّاف

الرصيد ثابت وقيمته 500. اقرأ مبلغ السحب amount عددًا صحيحًا، وتحقق بهذا الترتيب: إذا كان 0 أو أقل فاطبع Invalid amount، وإذا كان أكبر من الرصيد فاطبع Not enough balance، وإذا لم يكن من مضاعفات 10 فاطبع Use multiples of 10. وإلا فاطبع سطرين: Take <amount> ثم Balance: <remaining>. لا تطبع أي رسالة تطلب الإدخال.

import java.util.Scanner;

public class Withdraw {
    public static void main(String[] args) {
        final int BALANCE = 500;
        Scanner input = new Scanner(System.in);
        // Read the amount, then check each case in order

    }
}
stdin
100
الناتج المتوقع
Take 100
Balance: 400
تلميح 1

المضاعف لا يترك باقيًا: amount % 10 != 0 يعني أنه ليس من مضاعفات 10.

تلميح 2

لا يمكن تغيير قيمة الثابت، فاطبع BALANCE - amount مباشرة.

الحل
import java.util.Scanner;

public class Withdraw {
    public static void main(String[] args) {
        final int BALANCE = 500;
        Scanner input = new Scanner(System.in);
        int amount = input.nextInt();
        if (amount <= 0) {
            System.out.println("Invalid amount");
        } else if (amount > BALANCE) {
            System.out.println("Not enough balance");
        } else if (amount % 10 != 0) {
            System.out.println("Use multiples of 10");
        } else {
            System.out.println("Take " + amount);
            System.out.println("Balance: " + (BALANCE - amount));
        }
    }
}

يتبع else أقرب if مفتوح قبله، مهما كانت الإزاحة

تبدو كلمة else تابعة للشرط الأول، فهل هي كذلك؟ قيمة x هي 5.

public class DanglingElse {
    public static void main(String[] args) {
        int x = 5;
        if (x > 0)
            if (x > 10)
                System.out.println("Big");
        else
            System.out.println("Not positive");
        System.out.println("End");
    }
}
أظهر الناتج
الناتج
Not positive
End

لماذا؟ المترجم يتجاهل الإزاحة، ويربط else بأقرب if قبله، أي x > 10. فالعدد 5 موجب وليس أكبر من 10، فيُطبع Not positive، وهذا خطأ واضح في المعنى.

الأقواس تحسم الأمر

البرنامج نفسه، لكن الأقواس تربط else بالشرط الأول. اضغط «تتبّع سطرًا سطرًا»، ثم جرّب x = -2 وx = 20.

public class ElseWithBraces {
    public static void main(String[] args) {
        int x = 5;
        if (x > 0) {
            if (x > 10) {
                System.out.println("Big");
            }
        } else {
            System.out.println("Not positive");
        }
        System.out.println("End");
    }
}
الناتج
End

في الكود أعلاه دون أقواس: بأي if ترتبط else؟

السنة الكبيسة: قاعدة واحدة تجمع ثلاثة شروط

السنةتقبل القسمة على 4؟تقبل القسمة على 100؟تقبل القسمة على 400؟كبيسة؟
2024نعملالانعم
2023لالالالا
1900نعمنعملالا
2000نعمنعمنعمنعم

القاعدة: تكون السنة كبيسة إذا قبلت القسمة على 4 ولم تقبلها على 100، أو إذا قبلت القسمة على 400.

سمِّ كل جزء من الشرط

المتغيرات المنطقية ذات الأسماء الواضحة تجعل الشرط الطويل مقروءًا. جرّب السنوات الأربع في الجدول، وتتبّع القيم باستخدام «تتبّع سطرًا سطرًا».

public class LeapParts {
    public static void main(String[] args) {
        int year = 1900;
        boolean by4 = year % 4 == 0;
        boolean by100 = year % 100 == 0;
        boolean by400 = year % 400 == 0;
        System.out.println(by4);
        System.out.println(by100);
        System.out.println(by400);
        System.out.println((by4 && !by100) || by400);
    }
}
الناتج
true
true
false
false

هل السنة كبيسة؟

اقرأ سنة، ثم اطبع Leap year إذا كانت كبيسة، وإلا فاطبع Not a leap year. لا تطبع أي رسالة تطلب الإدخال.

import java.util.Scanner;

public class LeapYear {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        // Read the year, then apply the rule

    }
}
stdin
2024
الناتج المتوقع
Leap year
تلميح 1

«يقبل القسمة على 4» تعني year % 4 == 0.

تلميح 2

(year % 4 == 0 && year % 100 != 0) || year % 400 == 0، والأقواس تجعله واضحًا.

الحل
import java.util.Scanner;

public class LeapYear {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int year = input.nextInt();
        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
            System.out.println("Leap year");
        } else {
            System.out.println("Not a leap year");
        }
    }
}
الجزء الثالث: switch والعامل الثلاثي

الأمر switch يقفز إلى الحالة التي تساوي القيمة

switch (value) {
    case 1:
        // runs when value is 1
        break;      // leave the switch
    case 2:
        // runs when value is 2
        break;
    default:
        // runs when no case matches
}
تأتي بعد كل case قيمة ثابتة ونقطتان رأسيتان، ولا يلزم وضع أقواس حول الأسطر.

اسم اليوم

اليوم 1 هو الأحد. اضغط «تتبّع سطرًا سطرًا» لترى القفز المباشر إلى case 3. ثم جرّب day = 9 لترى عمل default.

public class DayName {
    public static void main(String[] args) {
        int day = 3;
        switch (day) {
            case 1:
                System.out.println("Sunday");
                break;
            case 2:
                System.out.println("Monday");
                break;
            case 3:
                System.out.println("Tuesday");
                break;
            case 4:
                System.out.println("Wednesday");
                break;
            case 5:
                System.out.println("Thursday");
                break;
            default:
                System.out.println("Weekend or not a day");
        }
        System.out.println("Done");
    }
}
الناتج
Tuesday
Done

متى يُنفَّذ default؟

دون break يكمل البرنامج إلى الحالات التالية

تأمل أماكن break جيدًا. قيمة n هي 2. ماذا يطبع؟

public class FallThrough {
    public static void main(String[] args) {
        int n = 2;
        switch (n) {
            case 1:
                System.out.println("One");
            case 2:
                System.out.println("Two");
            case 3:
                System.out.println("Three");
                break;
            case 4:
                System.out.println("Four");
            default:
                System.out.println("Other");
        }
    }
}
أظهر الناتج
الناتج
Two
Three

لماذا؟ يقفز البرنامج إلى case 2، ثم يتابع النزول سطرًا سطرًا دون فحص أي case أخرى حتى يصل إلى break. ويسمى هذا السلوك السقوط (fall-through).

سعر خاطئ بسبب break مفقود

الحجم 1 سعره 5، لكن البرنامج يطبع 10. اضغط «تتبّع سطرًا سطرًا» وراقب price وهي تتغير ثلاث مرات. ثم أضف break في مكانها حتى يطبع Price: 5.

public class SizePrice {
    public static void main(String[] args) {
        int size = 1;
        int price = 0;
        switch (size) {
            case 1:
                price = 5;
            case 2:
                price = 8;
            case 3:
                price = 10;
                break;
            default:
                price = 0;
        }
        System.out.println("Price: " + price);
    }
}
الناتج
Price: 10

السقوط المقصود يجمع عدة حالات في جواب واحد

أيام الشهر

سبعة أشهر فيها 31 يومًا. اكتب الحالات فوق بعضها، فتسقط كلها إلى السطر نفسه. اضغط «تتبّع سطرًا سطرًا»، ثم غيّر month إلى 1 ثم 2 ثم 13.

public class DaysInMonth {
    public static void main(String[] args) {
        int month = 4;
        int days;
        switch (month) {
            case 1: case 3: case 5: case 7:
            case 8: case 10: case 12:
                days = 31;
                break;
            case 4: case 6: case 9: case 11:
                days = 30;
                break;
            case 2:
                days = 28;
                break;
            default:
                days = 0;
        }
        System.out.println("Days: " + days);
    }
}
الناتج
Days: 30

أيام الشهر مع السنة الكبيسة

اقرأ رقم الشهر، ثم السنة. اطبع عدد أيام الشهر وحده، ويكون فبراير 29 يومًا في السنة الكبيسة. وإذا لم يكن الشهر من 1 إلى 12 فاطبع Invalid month. لا تطبع أي رسالة تطلب الإدخال.

import java.util.Scanner;

public class MonthDays {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int month = input.nextInt();
        int year = input.nextInt();
        // Use switch on month; put the leap-year check under case 2

    }
}
stdin
1
2023
الناتج المتوقع
31
تلميح 1

داخل case 2: اكتب if-else يستخدم قاعدة السنة الكبيسة، ثم break.

تلميح 2

اكتب رسالة الخطأ في default، واطبع عدد الأيام داخل كل حالة قبل break.

الحل
import java.util.Scanner;

public class MonthDays {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int month = input.nextInt();
        int year = input.nextInt();
        switch (month) {
            case 1: case 3: case 5: case 7:
            case 8: case 10: case 12:
                System.out.println(31);
                break;
            case 4: case 6: case 9: case 11:
                System.out.println(30);
                break;
            case 2:
                if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                    System.out.println(29);
                } else {
                    System.out.println(28);
                }
                break;
            default:
                System.out.println("Invalid month");
        }
    }
}

يعمل switch أيضًا مع char وString

وصف التقدير باستخدام char

تُكتب قيمة char بين علامتي تنصيص مفردتين. غيّر grade إلى 'a' ثم إلى 'Z'. لاحظ كيف تجمع case 'A': case 'a': بين الحرفين الكبير والصغير.

public class GradeWords {
    public static void main(String[] args) {
        char grade = 'B';
        switch (grade) {
            case 'A': case 'a':
                System.out.println("Excellent");
                break;
            case 'B': case 'b':
                System.out.println("Very good");
                break;
            case 'C': case 'c':
                System.out.println("Good");
                break;
            default:
                System.out.println("Unknown grade");
        }
    }
}
الناتج
Very good

أمر نصي من المستخدم

يعمل switch مع String منذ Java 7، وهو يقارن باستخدام equals، لذلك يعمل مع النصوص المقروءة بـ Scanner. غيّر المدخل إلى stop ثم إلى Start.

import java.util.Scanner;

public class Commands {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String command = input.next();
        switch (command) {
            case "start":
                System.out.println("Starting");
                break;
            case "stop":
                System.out.println("Stopping");
                break;
            default:
                System.out.println("Unknown command");
        }
    }
}
الناتج
Starting

المدخل هو Yes بحرف كبير. ماذا يطبع؟

import java.util.Scanner;

public class Confirm {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String reply = input.next();
        switch (reply) {
            case "yes":
                System.out.println("Confirmed");
                break;
            case "no":
                System.out.println("Cancelled");
                break;
            default:
                System.out.println("Please answer yes or no");
        }
    }
}
أظهر الناتج
الناتج
Please answer yes or no

لماذا؟ switch مع النصوص يقارن الحروف بدقة كما تفعل equals، وYes يختلف عن yes.

سعر التذكرة

اقرأ نوع التذكرة كلمة واحدة، واستخدم switch: child سعرها 5، وadult سعرها 10، وsenior سعرها 7. اطبع Price: <price>، ولأي كلمة أخرى اطبع Unknown ticket. لا تطبع أي رسالة تطلب الإدخال.

import java.util.Scanner;

public class Ticket {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String type = input.next();
        // Write the switch here

    }
}
stdin
child
الناتج المتوقع
Price: 5
تلميح 1

لا تنسَ break بعد كل حالة، وإلا طبع البرنامج عدة أسعار.

تلميح 2

تُكتب النصوص في case بين علامتي تنصيص مزدوجتين: case "child":.

الحل
import java.util.Scanner;

public class Ticket {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String type = input.next();
        switch (type) {
            case "child":
                System.out.println("Price: 5");
                break;
            case "adult":
                System.out.println("Price: 10");
                break;
            case "senior":
                System.out.println("Price: 7");
                break;
            default:
                System.out.println("Unknown ticket");
        }
    }
}

استخدم switch للقيم المحددة، وif لما عداها

الموقفالأنسبالسبب
رقم من قائمة خياراتswitchقيم محددة للمتغير نفسه
تقدير من علامةifمجالات من القيم، وليس قيمًا محددة
عمر وبطاقة معًاifأكثر من متغير واحد
درجة حرارة من نوع doubleifswitch لا يقبل double
حرف أمر مثل + أو -switchقيم char محددة

شرط في مكان القيمة

لا يقبل case شرطًا، بل قيمة ثابتة. أعد كتابة البرنامج باستخدام if-else ليطبع A.

public class CaseRange {
    public static void main(String[] args) {
        int mark = 95;
        switch (mark) {
            case mark >= 90:
                System.out.println("A");
                break;
            default:
                System.out.println("Not A");
        }
    }
}
رسالة المترجمincompatible types: boolean cannot be converted to int
أظهر التصحيح
public class CaseRange {
    public static void main(String[] args) {
        int mark = 95;
        if (mark >= 90) {
            System.out.println("A");
        } else {
            System.out.println("Not A");
        }
    }
}
الناتج
A

لماذا؟ يقارن switch القيمة mark من نوع int بقيمة كل حالة. وناتج mark >= 90 من نوع boolean، فلا يمكن مقارنته بـ int. ولهذا تتحدث الرسالة عن الأنواع. والمجالات عمل if.

حالتان بالقيمة نفسها

أراد المبرمج أن تطبع الحالة الثانية Friday للرقم 6. أصلح الرقم.

public class DuplicateCase {
    public static void main(String[] args) {
        int day = 6;
        switch (day) {
            case 5:
                System.out.println("Thursday");
                break;
            case 5:
                System.out.println("Friday");
                break;
            default:
                System.out.println("Other");
        }
    }
}
رسالة المترجمduplicate case label
أظهر التصحيح
public class DuplicateCase {
    public static void main(String[] args) {
        int day = 6;
        switch (day) {
            case 5:
                System.out.println("Thursday");
                break;
            case 6:
                System.out.println("Friday");
                break;
            default:
                System.out.println("Other");
        }
    }
}
الناتج
Friday

لماذا؟ لو سمح المترجم بحالتين متساويتين، لما عُرف إلى أيهما يقفز البرنامج. لذلك يجب أن تكون قيمة كل case فريدة داخل switch.

أي مسألة لا تناسب switch؟

العامل الثلاثي يختار بين قيمتين في تعبير واحد

result = condition ? valueIfTrue : valueIfFalse;
اقرأها: هل الشرط صحيح؟ إن كان كذلك فالقيمة الأولى، وإلا فالثانية.

سطر واحد بدل خمسة

غيّر mark إلى 45 وتوقّع الناتج. ثم أعد كتابة السطر الثالث باستخدام if-else وقارن الطريقتين.

public class Ternary {
    public static void main(String[] args) {
        int mark = 72;
        int bonus = mark >= 70 ? 5 : 0;
        String result = mark >= 60 ? "Pass" : "Fail";
        System.out.println(result);
        System.out.println("Bonus: " + bonus);
    }
}
الناتج
Pass
Bonus: 5

يمكن وضعه داخل الطباعة مباشرة، بين قوسين. ماذا يطبع؟

public class TernaryPrint {
    public static void main(String[] args) {
        int x = 7;
        System.out.println(x + " is " + (x % 2 == 0 ? "even" : "odd"));
        int max = x > 10 ? x : 10;
        System.out.println(max);
    }
}
أظهر الناتج
الناتج
7 is odd
10

لماذا؟ باقي قسمة 7 على 2 هو 1، فالشرط false ونأخذ "odd". وفي السطر الثاني 7 ليست أكبر من 10، فنأخذ 10.

سعر حسب العمر

اقرأ العمر، ثم استخدم العامل الثلاثي لتعطي price القيمة 5 إذا كان العمر أقل من 12، وإلا فالقيمة 10. اطبع Price: <price>. لا تطبع أي رسالة تطلب الإدخال.

import java.util.Scanner;

public class AgePrice {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int age = input.nextInt();
        // int price = ... ? ... : ...;

    }
}
stdin
5
الناتج المتوقع
Price: 5
تلميح 1

الشرط هو age < 12، ويأتي قبل العلامة ?.

الحل
import java.util.Scanner;

public class AgePrice {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int age = input.nextInt();
        int price = age < 12 ? 5 : 10;
        System.out.println("Price: " + price);
    }
}

أسئلة المراجعة

كم فرعًا ينفَّذ على الأكثر في سلسلة if وelse if وelse؟

ماذا يحدث إذا نسيت break في case؟

أي نوع لا يقبله switch في Java 8؟

توقّع: سلسلة، ثم switch، ثم عامل ثلاثي.

public class ReviewMixed {
    public static void main(String[] args) {
        int n = 15;
        if (n > 20) {
            System.out.println("High");
        } else if (n > 10) {
            System.out.println("Mid");
        } else {
            System.out.println("Low");
        }
        switch (n % 4) {
            case 3:
                System.out.println("Three");
            case 2:
                System.out.println("Two");
                break;
            default:
                System.out.println("Other");
        }
        System.out.println(n > 10 ? "Yes" : "No");
    }
}
أظهر الناتج
الناتج
Mid
Three
Two
Yes

لماذا؟ 15 أكبر من 10 وليست أكبر من 20، فيُطبع Mid. وباقي قسمة 15 على 4 هو 3، فيقفز البرنامج إلى case 3 ويسقط إلى case 2 حتى break. ثم يطبع العامل الثلاثي Yes.