Kapag nagsusulat ng code na may maraming kundisyon, tiyak na gumamit ka ng if-else o switch statement. Ngunit ang alternatibong ito sa if-else ay may mga kakulangan. Tinawag pa nga ng ilang tao ang switch statement na "anti-pattern".

Ano yan? Ang isang anti-pattern ay isang karaniwang pattern ng masamang code, ibig sabihin, isang masamang solusyon sa isang problema. Sinisikap ng mga programmer na iwasan ang mga ito sa code, dahil pinapababa nila ang kalidad ng code.

Ngunit may magandang balita: ang mga bagong bersyon ng Java ay nagdala ng maraming pagbabago sa syntax ng wika, at ang isa sa mga pagbabagong iyon ay nakakaapekto sa switch . naiintriga? Pagkatapos ay sumisid na tayo.

Upang magsimula sa, ito ay nagkakahalaga ng paglilinaw kung bakit ang switch ay isang anti-pattern. Isaalang-alang ang sumusunod na code:


switch (condition) {
    case "DECEMBER":
        seasonNumber = 1;
        break;
    case "JANUARY":
        seasonNumber = 1;
        break;
    case "FEBRUARY":
        seasonNumber = 1;
        break;
    default:
        seasonNumber = 0;
}

Okay, kaya hindi pa ganap na malinaw kung bakit ito ay isang "anti-pattern".

Ngunit paano kung magdagdag kami ng higit pang mga bloke ng kaso at ngayon ang code ay ganito:


switch (condition) {
    case "DECEMBER":
        seasonNumber = 1;
        break;
    case "JANUARY":
        seasonNumber = 1;
        break;
    case "FEBRUARY":
        seasonNumber = 1;
        break;
    case “MARCH”:
        seasonNumber = 2;
        break;
    case “APRIL”:
        seasonNumber = 2;
        break;
    case “MAY”:
        seasonNumber = 2;
        break;
    default:
        seasonNumber = 0;
}

Magdagdag pa tayo ng ilang linya — mas humahaba ang code. Sa ibang pagkakataon, maaari tayong magdagdag ng higit pa at higit pang mga linya, at walang makakapigil sa atin na gawin ito.

Ito ang puso ng problema: pagkatapos gumawa ng isang compact switch statement sa simula, nagdaragdag kami ng higit at higit pang code dito, kumukuha ng mas maraming espasyo — higit pa sa kakasya sa screen — at ginagawang hindi maginhawang basahin at panatilihin ang code.

Pagkakaiba sa pagitan ng switch statement at switch expression

Ipinakilala ng Java 14 ang bago at pinahusay na switch. Ito ay hindi isang switch statement , ngunit sa halip ay isang switch expression .

Ano ang pagkakaiba, itatanong mo? Ang pagkakaiba ay ang isang pahayag ay isang pagtuturo na nagsasagawa ng isang tiyak na hanay ng mga operasyon, ngunit ang isang expression ay isang piraso ng code na nagsasagawa ng ilang pagkalkula at nagbabalik ng isang resulta.

Sa madaling salita, maaari mo na ngayong i-save ang resulta ng isang paglipat sa isang variable.

Enough talking. Ngayon tingnan natin kung ano ang hitsura ng bagong switch :


var result = switch(month) {
     case DECEMBER, JANUARY, FEBRUARY -> 1;
     case MARCH, APRIL, MAY -> 2;
    case JUNE, JULY, AUGUST -> 3;
    case SEPTEMBER, OCTOBER, NOVEMBER -> 4;
    default -> 0; 
};

Ang unang bagay na nakakakuha ng iyong mata ay kung gaano ka compact ang code. Ang code na ginamit sa karamihan ng screen ay sumasaklaw na ngayon ng ilang linya at mukhang mas nababasa.

-> operator

Dapat mo ring tandaan ang -> operator (operator ng arrow). Maaaring pamilyar ka na dito kung mayroon kang karanasan sa mga expression ng lambda.

Ibig sabihin, maaari ka na ngayong magsulat ng isang cool-looking switch sa istilo ng isang lambda statement. Ang arrow operator ay nagpapahiwatig na ang compiler ay hindi magpapatuloy sa susunod na case expression (kung ang kasalukuyang case block ay walang break o return statement), ngunit sa halip ay bibigyan ka ng halaga ng expression sa kanan ng arrow.

Maaari ka ring magsulat ng code na hindi isang expression at simpleng gumaganap ng ilang mga aksyon sa halip na ibalik ang anuman:


switch(condition) {
    case TRUE, FALSE -> System.out.println("True/false");
  
    default -> System.out.println("Another");
}

Tandaan na wala nang break statement ang switch . Inalis ito sa Java 13 at pinalitan ng yield .

Ano ang ani at saan ito magagamit?

Kapag ang switch ay binubuo ng isang linya, ang -> operator mismo ang nagbabalik ng halaga. Ngunit paano kung wala tayong isa, ngunit maraming linya ng code? Sa ganitong mga kaso, hindi magbabalik ng value ang arrow operator, dahil maraming linya, hindi isa.

Siguro magagamit natin ang pagbabalik ? Pagkatapos ng lahat, ito ay ginagamit upang ibalik ang mga halaga sa Java. Naku, hindi, hindi gagana ang pagbabalik sa isang switch. Kaya ano ang maaari naming gamitin? Dati ay may break , ngunit inalis iyon sa Java 13. Ngunit kapalit nito ay mayroon na kaming yield — isang bagong keyword na tumutulong sa iyong magbalik ng halaga mula sa isang switch. Ito ay kahalintulad sa pagbabalik ng mga pahayag sa mga pamamaraan.


var result = switch(condition) {
//…
case "Hi" -> "greeting"
//…
};  

Ang code na ito ay naglalaman ng isang linya, at ang -> operator ay magbabalik ng "pagbati".

Ngunit kapag mayroon kaming isang bloke ng code:


var result = switch(condition) {
//…
case "Hi" -> {
// Your code
 Here you need to return "greeting"
	}
};  

Ang keyword na tutulong sa iyong ibalik ang isang halaga ay yield :


var result = switch(condition) {
//…
case "Hi" -> {
// Your code
 yield "greeting";

	}
};

idinagdag ang yield sa Java 13 para sa mga kaso kung saan mayroon kaming higit sa isang linya ng code sa isang case block at kailangan naming magbalik ng resulta.

Marahil ay sabik kang subukan ang bagong switch sa iyong code, ngunit tandaan na kailangan mo ng Java 14 o mas mataas para magawa ito. Sa mga naunang bersyon, magiging available lang ang switch na ito kung tinukoy mo ang flag na "--enable-preview" sa command line, dahil bago ang bersyon 14 ay bahagi ito ng teknikal na preview, hindi isang ganap na bahagi ng wika .

Yun lang muna! See you!