switch
-statement, modernising and simplifying it.break
-statements!->
” now!switch
as an expression (meaning it can evaluate to a value to be assigned or returned),The introduction of switch expressions brings new syntax and keywords that streamline coding practices:
Feature | Description | Benefit |
---|---|---|
Arrow (-> ) | Directs the output for each case without requiring break statements. | Eliminates fall-through errors, simplifying control flow. |
Multiple case labels | Multiple case labels can be combined using commas to share a single output. | Reduces code redundancy, making it cleaner and more concise. |
yield Keyword | Used to return a value from a block of code within a switch case. | Facilitates returning complex values from multi-statement cases. |
Default case | Used as a fallback if no other case matches, now mandatory in switch expressions. | Ensures all scenarios are covered, improving code robustness. |
Before Java 17:
With classic switch
-statements, we had to be extra aware of using the break
-statement correctly, and fall-through logic could get quite verbose..
public static void main(String[] args) { String day = "Saturday"; switch (day) { case "Monday": case "Tuesday": case "Wednesday": case "Thursday": case "Friday": System.out.println("It's a work day"); break; case "Saturday": case "Sunday": System.out.println("It's weekend"); break; default: throw new IllegalArgumentException("Invalid day: " + day); } }
After Java 17:
With the new syntax, we can use multiple case labels at a time to keep our code concise, and we don’t need to worry about accidentally forgetting a break
-statement as the arrow syntax takes care of that for us.
public class DaysOfWeekAfterDemo { public static void main(String[] args) { String day = "Saturday"; switch (day) { case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" -> System.out.println("It's a work day"); case "Saturday", "Sunday" -> System.out.println("It's weekend"); default -> throw new IllegalArgumentException("Invalid day: " + day); } } }
It gets even cooler when you realise we can use switch
-expressions now:
public static void main(String[] args) { String day = "Saturday"; String message = switch (day) { case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" -> "It's a work day"; case "Saturday", "Sunday" -> "It's weekend"; default -> throw new IllegalArgumentException("Invalid day: " + day); }; System.out.println(message); }
Being able to assign the result to a variable is quite a powerful, functional way of programming that can help us keep our code much more concise and less repetitive.
yield
Keywordyield
” keyword?return
(duh, that’s for methods), but a yield
.yield
ing “It’s a work day” or “It’s weekend”, but because it’s just a one-liner, Java lets us omit it for brevity (but it’s there implicitly!).yield
keyword.public static void main(String[] args) { String day = "Saturday"; String message = switch (day) { case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" -> { // More lines of code here yield "It's a work day"; } case "Saturday", "Sunday" -> { // More lines of code here yield "It's weekend"; } default -> throw new IllegalArgumentException("Invalid day: " + day); }; System.out.println(message); }
So yield
acts as a kind of mini-return
, but for switch
-expressions, and it’s not even necessary to explicitly use it if your case-logic is a one-liner.
switch
: How to Write itSwitch expressions introduce a new syntax that is more concise and safer than the traditional switch statement. Here’s how to write a switch expression step-by-step:
switch
keyword, followed by the variable you are switching on enclosed in parentheses, then use curly braces to enclose a scope.case
keyword, followed by the label you want this case-logic to be associated with.->
) after each case label to signify what should happen for that label. This operator eliminates the need for break
statements.yield
keyword within a block if the case requires multiple statements or complex logic to determine the return value. Note: This is only relevant for switch
-expressions, not switch
-statements.default
case to define what happens if none of the specified cases match the input.What is the primary advantage of using the arrow (->
) syntax in switch expressions introduced in Java 14?
A) It allows for fall-through behavior.
B) It eliminates the need for break
statements.
C) It supports multiple switch cases.
D) It makes the switch expression faster.
public class DaysInMonth { public static _____ getDays(int month, boolean isLeapYear) { _______ switch (month) { _______ 1, 3, 5, 7, 8, 10, 12 -> 31; _______ 4, 6, 9, 11 -> 30; _______ 2 __ isLeapYear ? __ : __; _______ -> throw new IllegalArgumentException("Invalid month: " + month); }; } public static void main(String[] args) { int days = getDays(2, true); System.out.println("Days: " + days); } }
Identify and correct the errors in the following Java code that is supposed to use a switch expression to output the type of website based on URL.
public class WebsiteType { public static String getWebsiteType(String url) { return switch (url) { case url.contains("edu") -> "Educational"; case url.contains("org") -> "Organization"; case url.contains("com") -> "Commercial"; case url.contains("net") -> "Network"; default -> "Unknown"; }; } public static void main(String[] args) { String type = getWebsiteType("http://www.example.com"); System.out.println("Website Type: " + type); } }
In this exercise, you will work with a simple grading system that categorizes scores into grades (A, B, C, D, F), first with a classic switch
-statement, then with the new syntax!
GradingApp
-class, ask the user to enter a grade (A, B, C, D or F).Route helpdesk tickets based on the nature of the query. Tickets related to “software”, “hardware”, or “network” might route to different departments but some might fall through to a default support group.
HelpDeskApp
-class, ask the user to enter a query category depending on their issue (i.e. “software”, “hardware”, “network”, etc.).routeTicket
-method that accepts a query category and returns the name of the department (with phone number).makeCoffee()
-method is called before yielding the name of the department (you’ll have to use curly braces and the yield
-keyword to solve this).main
-method, after asking the user to input a query category, pass this to the routeTicket
-method to obtain the department name and phone number, and print it.Answer: B) It eliminates the need for break
statements.
public class DaysInMonth { public static _____ getDays(int month, boolean isLeapYear) { _______ switch (month) { _______ 1, 3, 5, 7, 8, 10, 12 -> 31; _______ 4, 6, 9, 11 -> 30; _______ 2 __ isLeapYear ? __ : __; _______ -> throw new IllegalArgumentException("Invalid month: " + month); }; } public static void main(String[] args) { int days = getDays(2, true); System.out.println("Days: " + days); } }
public class DaysInMonth { public static int getDays(int month, boolean isLeapYear) { return switch (month) { case 1, 3, 5, 7, 8, 10, 12 -> 31; case 4, 6, 9, 11 -> 30; case 2 -> isLeapYear ? 29 : 28; default -> throw new IllegalArgumentException("Invalid month: " + month); }; } public static void main(String[] args) { int days = getDays(2, true); System.out.println("Days: " + days); } }
public class WebsiteType { public static String getWebsiteType(String url) { if (url.contains("edu")) { return "Educational"; } else if (url.contains("org")) { return "Organization"; } else if (url.contains("com")) { return "Commercial"; } else if (url.contains("net")) { return "Network"; } else { return "Unknown"; } } public static void main(String[] args) { String type = getWebsiteType("http://www.example.com"); System.out.println("Website Type: " + type); } }
public class WebsiteType { public static String getWebsiteType(String url) { if (url.contains("edu")) { return "Educational"; } else if (url.contains("org")) { return "Organization"; } else if (url.contains("com")) { return "Commercial"; } else if (url.contains("net")) { return "Network"; } else { return "Unknown"; } } public static void main(String[] args) { String type = getWebsiteType("http://www.example.com"); System.out.println("Website Type: " + type); } }
case
labels in a switch expression cannot use method calls like contains
.url
in a if-else structure or modify the design to use a pattern matching approach in Java 21 and later versions (see below).public class WebsiteType { public static String getWebsiteType(String url) { return switch (url) { case String s when s.contains("edu") -> "Educational"; case String s when s.contains("org") -> "Organization"; case String s when s.contains("com") -> "Commercial"; case String s when s.contains("net") -> "Network"; default -> "Unknown"; }; } public static void main(String[] args) { String type = getWebsiteType("http://www.example.com"); System.out.println("Website Type: " + type); } }
public class GradingApp { public static void main(String[] args) { Scanner keyboard = new Scanner(System.in); System.out.print("Enter your grade (A, B, C, D or F): "); String inputGrade = keyboard.nextLine(); // Classic switch statement switch (inputGrade) { case "A": System.out.println("That's excellent!"); break; case "B": System.out.println("Good job!"); break; case "C": System.out.println("Not bad..."); break; case "D": System.out.println("Oof! Better luck next time!"); break; case "F": System.out.println("An F!? Better get to studying!"); break; default: throw new IllegalArgumentException("Invalid grade: " + inputGrade); } // Refactored modern switch statement switch (inputGrade) { case "A" -> System.out.println("That's excellent!"); case "B" -> System.out.println("Good job!"); case "C" -> System.out.println("Not bad..."); case "D" -> System.out.println("Oof! Better luck next time!"); case "F" -> System.out.println("An F!? Better get to studying!"); default -> throw new IllegalArgumentException("Invalid grade: " + inputGrade); } // Refactored switch expression String message = switch (inputGrade) { case "A" -> "That's excellent!"; case "B" -> "Good job!"; case "C" -> "Not bad..."; case "D" -> "Oof! Better luck next time!"; case "F" -> "An F!? Better get to studying!"; default -> throw new IllegalArgumentException("Invalid grade: " + inputGrade); }; System.out.println(message); } }
public class HelpDeskApp { public static void main(String[] args) { Scanner keyboard = new Scanner(System.in); System.out.print("Enter your query category (Software, Hardware, etc.): "); String inputQueryCategory = keyboard.nextLine(); String department = routeTicket(inputQueryCategory.toLowerCase()); System.out.println(department); } private static String routeTicket(String queryCategory) { return switch (queryCategory) { case "software" -> { makeCoffee(3); yield "Software Support Team | +32 400 000 121"; } case "hardware" -> "Hardware Support Team | +32 400 000 122"; case "network", "internet", "connectivity" -> "Network Support Team | +32 400 000 123"; default -> "General Support Team | +32 400 000 000"; }; } private static void makeCoffee(int cups) { System.out.printf("Making %d cups of coffee...\n", cups); } }
break
statements, thanks to the new ->
arrow operator, which prevents errors and simplifies the code.yield
to return values from complex case scenarios within switch expressions, enhancing clarity and control.