[조건문] switch-case vs if-else
조건문을 수행하는 구문에는
if-else 구문과 Switch-case 구문이 있다.
if - else 구문
if(조건문) {조건문이 true일 때 수행할 실행문
} else { 조건문이 false일 때 수행할 실행문
}
- if 다음에 나오는 ()괄호 안에 조건식을 쓴다.
- ()안의 조건이 true일 때 수행할 문장을 if문의 {} 안에 작성한다.
- ()안의 조건이 false일 때 수행할 문장을 else문의 {}안에 작성한다.
else를 꼭 쓰지 않아도된다.
=> else문을 쓰지 않고 if(조건문){조건문이 true일 때 수행할 실행문}만 작성한다면
조건이 false일 때는 if문 바깥으로 탈출한다.
조건을 여러개 묶어주고 싶다면?
-> else if 문을 써준다.
if ( 조건문 1 ) { 조건문1이 true 일때 수행 할 실행문 }
else if ( 조건문 2 ) { 조건문2가 true 일때 수행 할 실행문 }
else { 조건문 1과 2 가 모두 false 일 때 수행 할 실행문 }
예시를 들자면
public class Main{
public static void main(String[] args) throws IOException{
int temperature = 20;
if (temperature > 26){
System.out.print("더운 날씨입니다.");
} else if (temperature > 15){
System.out.print("선선한 날씨입니다.");
} else {
System.out.print("쌀쌀한 날씨입니다.");
}
}
}
온도가 26도 초과일때 "더운 날씨입니다."
온도가 15도 미만일때 "쌀쌀한 날씨입니다."
그 중간 조건에서는 "선선한 날씨입니다." 를 출력한다.
이처럼 여러 개의 조건을 적용할 때 else if를 사용할 수 있다.
else if 문은 if문, else문 사이에 여러번 써도 상관 없다.
단, if문과 else문은 단 한번만 작성 가능하다.
Switch-case문
switch(변수) {
case 값1: 실행문1;
case 값2: 실행문2;
case 값3: 실행문3;
default: 실행문4;
}
switch의 ()안에 변수를 저장하고,
변수의 값이 값 1일때 실행문 1을 수행하고,
변수의 값이 값 2일때 실행문 2을 수행하고,
변수의 값이 값 3일때 실행문 3을 수행하고,
모두 아니면 default값의 실행문 4를 수행한다.
public class Main{
public static void main(String[] args) {
int grade = 2;
switch(grade) {
case 1: System.out.println("1등급입니다.");
case 2: System.out.println("2등급입니다.");
case 3: System.out.println("3등급입니다.");
default: System.out.println("등급이 없습니다.");
}
}
}
if -else 구문이 여러개의 조건을 지정하려면 else-if 문을 계속 생성하며 코드가 길어졌다.
switch-case 문은 비교적 코드가 쉽고 간단하다는 장점이 있다.
if-> switch, switch -> if 문의 변환이 가능하지만,
"모든 if 문이 모두 switch로 변환되지 만은 않는다"
if문은 비교연산자를 통해 범위를 지정하는 조건식을 작성할 수 있다.
반면 switch문은 변수의 값이 어떤 수치나 문자로 명시되는 경우로 분류되어 상대적 제약이 있다.
예를들어
if문은 조건식에 if( 20< A && A< 50) 과 같이 포괄적인 범위 지정이 되지만,
switch 문은 조건식에 switch(a) {case 20: 실행문;} 과 같이 정확히 명시되는 값에서만 분류가능하다.
둘 중 어느 것을 사용하는 것이 좋을까?
Switch문이 좋다
if - else 구문은 각각의 조건문을 모두 iterate하며 control flow를 결정한다.
N개의 if - else 구문은 N개의 조건문이 진위여부를 판단한다.
반면 switch 구문은 if - else 문과 다르다.
JVM 에서는 switch 구문 안의 case값들의 분포에 따라 내부적으로 각각의 상황에 최적화 된 자바 바이트코드를 생성하는데,
공통적으로 두 경우 모두 HashTable이 연상되는 구조를 지니고 있다.
case 값들이 서로 큰 차이가 없이 붙어있을 경우 TabelSwitch 형식의 컴파일을 수행하고,
(TabelSwitch형식 : 스택의 꼭대기에서 얻은 값들을 전달하여 label을 찾아 바로 jump하는 방식)
case 값들이 크게 차이가 날 경우 LookupSwitch 형식을 사용한다 (예를들어 case 값이 1, 17, 150일때)
(LookupSwitch형식: 이진 탐색트리 형식으로 저장된 구조에서 key값을 찾아 key와 연결된 label을 통해 jump하는 형태
그래서 switch 컴파일 방식은 구조가 HashTable, List와 비슷하다.
결국 switch문은 item의 개수(N)에 따라 O(lgN) 에 실행된다.
if else문은 item의 개수에따라 O(N)에 실행된다.