开发者

Better: switch-case or if-else? [duplicate]

This question already has answers here: Closed 11 years ago.

Possible Duplicate:

If/Else vs. Switch

I have two codes here, i just wanted to ask which of the two is better in terms of writability(ease of writing the codes) and in terms of readability (ease of understanding the codes).

switch-case:

import java.io.*;

public class Quarter{
    public static void main(String[] args){
        int day;
        String input="";

        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

        System.out.print("Input a number from 1 to 3: ");

        try{
            input=in.readLine();
        }catch(IOException e){
            System.out.println("Error!");
        }
        day=Integer.parseInt(input);

        switch(day){
            case 1:
            case 2:
            case 3:
                System.out.println("1st Quarter");
                break;
    开发者_JS百科        case 4:
            case 5:
            case 6:
                System.out.println("2nd Quarter");
                break;
            case 7:
            case 8:
            case 9:
            System.out.println("3rd Quarter");
            break;
            case 10:
            case 11:
            case 12:
                System.out.println("4th Quarter");
                break;
            default: System.out.println("Error!");
        }

    }
}

if-else:

import java.io.*;

public class Days{
    public static void main(String[] args){
        int day;
        String input="";

        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

        System.out.print("Input a number from 1 to 12: ");

        try{
            input=in.readLine();
        }catch(IOException e){
            System.out.println("Error!");
        }
        day=Integer.parseInt(input);

        if(day>=1 && day<=3){
            System.out.println("1st Quarter");
        }else
        if(day>=4 && day<=6){
            System.out.println("2nd Quarter");
        }else
        if(day>=7 && day<=9){
            System.out.println("3rd Quarter");
        }else
        if(day>=10 && day<=12){
            System.out.println("4th Quarter");
        }else
            System.out.println("Error!");
    }
}


Neither, I'd do this one:

String[] out = {
    "1st Quarter",
    "2nd Quarter",
    "3rd Quarter",
    "4th Quarter"
};

if (1 <= day && day <= 12) {
    System.out.println(out[(day - 1) / 3]);
} else {
    System.out.println("Error!");
}


  • Avoid the need for the logic to branch in the first place. Table lookup is often a useful technique. Arithmetic manipulation is also important - look for a pattern in the values you care about, and a function that transforms them into something simpler. Also consider polymorphism in more complex cases.

  • If you are handling all the exceptions the same way, then do it in the same place.

  • Scope variables tightly where possible.

  • Prompt for the input you actually want, FFS. :)

import java.io.*;

public class Quarter {
    public static void main(String[] args) {
        try {
            System.out.print("Input the month number (1 = January, 2 = February ... 12 = December): ");
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            int month = Integer.parseInt(in.readLine());
            int quarter = (month - 1) / 3;
            String[] quarters = new String[]{ "1st", "2nd", "3rd", "4th" };
            System.out.println(quarters[quarter] + " Quarter");
        } catch (Exception e) { // IOException for non-numeric, or AIOOBE for out of range
            System.out.println("Error!");
        }
    }
}


Which one would you prefer? It is your code.

I definitely prefer the switch-case, but if you have something combined or e.g. 'greater than' switch-case is not the right way to do it.

Another thing: I would write the switch case like the following, because I think it is better to read:

switch(day){
    case 1:
    case 2:
    case 3:
        System.out.println("1st Quarter");
        break;
...        
}

HTH, Andreas


What about :

(day>=1 && day <=3) ? System.out.println("1st Quarter") :
  (day >= 4 && day <= 6) ? System.out.println("2nd Quarter") :
    (day >=7 && day <= 9) ? System.out.println("3rd Quarter") :
      (day >= 10 && day <= 12) ? System.out.println("4th Quarter") : System.out.println("Error1");

;)

You could also do this:

String val = (day>=1 && day <=3) ? "1st Quarter" :
      (day >= 4 && day <= 6) ? "2nd Quarter" :
        (day >=7 && day <= 9) ? "3rd Quarter" :
          (day >= 10 && day <= 12) ? "4th Quarter" : "Error1";
System.out.println(val);

I think either should work.


It's not clear to me if the question is about solutions to the specific code example, or about the structure in general. So, some virtues of the if-else approach for consideration.

  • if-else is more common in code overall, because the number of datatypes accepted by switch is limited and switch itself is limited to compile time values. More familiar is better for readability for a broader audience.

  • The fundamental structure doesn't change if you find your requirements changing and you need to support a different datatype. I've had to change plenty of switches on enums to string compares in my time when someone added a requirement that the users be able to configure the options.

  • The need to use break; properly inside switches introduces opportunities for odd bugs that only show up in corner cases as the switches grow large and complicated.

Of course personally being an enterprise programmer I would have created a timeUnitSubDivisionResolvingVisitor ... :)


String[] suffix = new String[]{ "st", "nd", "rd", "th" };
System.out.println((1 <= day && day <= 12)?
    String.format("%d%s Quarter", (day-1)/3+1, suffix[(day-1)/3]):
    "Error!"
);


just an alternative way of implementing it is through a Map. It will make it configurable especially is you're using Spring where you can have this Map variable setup in your bean.xml if you decide to.

Anyway here is the alternative:

Map<Integer, String> m = new HashMap<Integer, String>();
m.put(1, "1st Quarter");
m.put(2, "1st Quarter");
m.put(3, "1st Quarter");
m.put(4, "2nd Quarter");
m.put(5, "2nd Quarter");
m.put(6, "2nd Quarter");
m.put(7, "3rd Quarter");
m.put(8, "3rd Quarter");
m.put(9, "3rd Quarter");
m.put(10, "4th Quarter");
m.put(11, "4th Quarter");
m.put(12, "4th Quarter");

System.out.println(m.get(d));
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜