모든 값, 범위를 기반으로 판단하는 if 문과 달리 정수 값이나 열거된 값 또는 문자, 문자열만을 사용할 수 있다.
컴파일러를 통해 실행 경로를 설정하는 점프 테이블이라는 것이 만들어지게 되어서 많은 조건을 비교하여야 할 때, if else 보다 더 빠른 성능을 보이게 된다.
→ case의 수가 5개 이상이라면, 성능 차이가 보이기 시작한다.
if else에 비하여서 좋은 가독성을 가지고 있다.
switch 문
public static String monthCheck(int num){
int days = 0;
switch (num) {
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 = -1;
};
return "입력하신 달은 "+days+"일 입니다.";
}
if else 문 (비교 용)
public static String monthCheck(int num){
int days = 0;
if (num == 1 || num == 3 || num == 5 || num == 7 || num == 8 || num == 10 || num == 12){
days = 31;
} else if (num == 4 || num == 6 || num == 9 || num == 11){
days = 30;
} else if (num == 2){
days = 28;
} else {
days = -1;
}
return "입력하신 달은 "+days+"일 입니다.";
}
반복문?
어떠한 명령을 일정한 횟수만큼 반복하여 수행하도록 하는 명령문이다.
1부터 100까지를 더하는 코드를 여러 방법으로 작성해보았다.
while 문
조건 식이 맞는 경우 실행되는 반복문이다. (bool 값을 통해 반복한다.)
구조
while(조건식){
//do something
}
// 무한 루프 : 사용시 조건 검증과 break; 을 통해 탈출해야한다.
while(true){
//do something
}
public static void whiles(){
int total = 0;
int loopCount = 1;
while(loopCount <= 100){
total += loopCount;
++loopCount;
}
System.out.println(total);
}
do / while 문
while 문과 비슷하지만 조건 식이 만족되지 않더라도 무조건 한 번은 실행되는 반복문이다.
구조
do{
//do something
}while(조건식);
// 무한 루프 : 사용시 조건 검증과 break; 을 통해 탈출해야한다.
do{
//do something
}while(true);
코드
public static void doWhiles(){
int total = 0;
int loopCount = 1;
do {
total += loopCount;
++loopCount;
}while(loopCount <= 100);
System.out.println(total);
}
for 문
반복된 횟수가 고정된 경우 사용하거나, index 위치나 값이 필요한 경우 사용한다.
구조
for(조건식){
//do something
}
// 무한 루프 : 사용시 조건 검증과 break; 을 통해 탈출해야한다.
// 해당 구문은 디컴파일 시 While(true)로 변경되어 있다.
for(;;){
//do something
}
코드
public static void fors(){
int total = 0;
for (int loopCount = 0; loopCount <= 100; loopCount++) {
total += loopCount;
}
System.out.println(total);
}
labeled for 문
각각의 for 문에 대하여서 라벨을 부여함으로써 중첩 for문에서 조건에 따라 중단하거나 계속하게끔 사용하기 좋다.
내부에 중첩된 for 문에 대해서도 라벨 부여가 가능하다.
구조
label:
for(조건식){
//do something
}
혹은
label:
for(조건식){
//do something
for(조건식){
//do something
break label;
// 혹은 continue;
}
}
코드
public static void labeledFors(){
int total = 0;
// 무한 루프
loop1: for (;;){
for (int inLoop=0;inLoop<=1000;inLoop++){
total += inLoop;
// 100번을 반복하게 되면 loop1을 탈출한다.
if(inLoop==100) {
break loop1;
}
}
}
System.out.println(total);
}
public static void enhancedFors(){
int total = 0;
int[] numArr = {10,20,30,40,50,60,70,80,90,100};
for (int num : numArr){
total += num;
}
System.out.println(total);
}
HashTable, Vector, Stack의 Enumeration
Collection Framework가 만들어지기 전에 사용되던 인터페이스이다.
순차 접근 시 컬랙션 객체의 내부가 수정되더라도 이를 무시하고, 끝까지 동작한다
→ Enumeration을 이용해서는 내부 요소를 수정할 방법이 없다. (읽기만 가능하다.)
→ 해당 컬랙션 내부의 수정 메서드를 이용하여야 한다.
Enumeration<String> enumeration = vector.elements();
// 읽어올 요소가 존재한다면, True 요소가 없다면 false를 반환한다.
enumeration.hasMoreElements()
// 다음 요소를 읽어올 때 사용한다.
enumeration.nextElement()
Collection의 Iterator()
Collection Framework 에서 사용되는 Enumeration을 보완한 인터페이스이다.
→ 요소를 제거하는 기능을 포함하였다. (remove)
Fail Fast Iterator (ArrayList, HashMap)
순차적 접근이 끝나기 전에 객체에 변경이 일어날 경우 예외를 반환한다.
→ 동일한 자원의 수정 발생 시 데이터의 일관성을 보장하기 위함이다.
내부적으로 변경, 수정된 횟수를 나타내는 modCount 필드가 있다.
하나 이상의 요소가 제거된 경우
하나 이상의 요소가 추가된 경우
컬렉션이 다른 컬렉션으로 대체되었을 때
컬렉션이 정렬될 때 등
→ 구조가 변경될 때마다 카운터가 증가하게 된다..
→ 데이터를 순회하는 동안 expectedModCount에 modCount 값을 저장하고 비교하며,
→ 두 개의 값이 달라질 경우 ConcurrentModificationException()를 발생시킨다.
→ next(), remove(), add(), remove(), forEachRemaining()에서 사용된다.
// 모든 테스트가 실행되기 이전에 1번 호출된다.
@BeforeAll
public static void beforeAll() {
System.out.println("AppTest.beforeAll");
}
// 모든 테스트가 실행된 이후에 1번 호출된다.
@AfterAll
public static void afterAll() {
System.out.println("AppTest.afterAll");
}
// 각각의 테스트가 실행되기 이전에 호출된다.
@BeforeEach
public void beforeEach() {
System.out.println("AppTest.beforeEach");
}
// 각각의 테스트가 실행된 이후에 호출된다.
@AfterEach
public void afterEach() {
System.out.println ("AppTest.afterEach");
}
@TestMethodOrder(OrderAnnotation.class)
class OrderedTest {
----------------------------
@Test
@Order(1)
void test_1() {
// do someThing
}
@Test
@Order(2)
void test_2() {
// do someThing
}
@Test
@Order(3)
void test_3() {
// do someThing
}
JUnit 5의 Test 이름 표시
@DisplayName("test name")
DisplayNameGenerator 보다 우선적으로 적용된다.
method 위에 작성한다.
@Test
@DisplayName("AAA Test")
void Arrange_Act_Assert() {
// Arrange : 생성
// Act : 조작
// Assert : 결과 비교
}
@DisplayNameGenerator
Class 내부의 모든 메서드에 적용된다.
Class 위에 작성한다.
// 모든 밑줄 문자를 공백으로 바꾸는 static class
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
// 표준 표시 생성 static class
@DisplayNameGeneration(DisplayNameGenerator.Standard.class)
Junit 5의 테스트에 대한 환경 변수 설정
@EnabledIfEnvironmentVariable : 지정된 환경 변수 값이 지정된 정규식과 일치하는 경우 활성화
@EnabledIfSystemProperty : JVM 시스템에 따라서 테스트를 활성화
@EnabledOnJre : 지정된 JRE (Java Runtime Environment) 버전에서만 활성화
@EnabledForJreRange : min으로 지정된 jre와 max로 지정된 jre 버전 사이에서 활성화
@EnabledOnOs : 지정된 운영 체제에서만 활성화
@EnabledIfEnvironmentVariable(named = "GDMSESSION", matches = "ubuntu") // ununtu 서버에서 실행
@EnabledIfSystemProperty(named = "java.vm.vendor", matches = "Oracle.*") // Oracle jvm에서 실행
@EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_13) // 8 ~ 13 버전의 자바에서 실행
@EnabledOnJre({JRE.JAVA_8, JRE.JAVA_9}) // 8, 9 버전의 자바에서만 실행
@EnabledOnOs({OS.WINDOWS, OS.LINUX}) // windows와 linux에서 실행
Junit5 Assertions
// assertEquals(A, B);
assertEquals("user", user.getUserName());
// assertTrue(A, B);
assertTrue("L", firstName.startsWith(user.getFirstName().charAt(0));
Exception exception = assertThrows(ArithmeticException.class, () -> calculator.divide(1, 0));
assertEquals("/ by zero", exception.getMessage());
// 시간 제한
assertTimeout(Duration.ofSeconds(1), () -> new user("Lob"));
// 시간이 초과되면 테스트 실패
assertTimeoutPreemptively(ofSeconds(1), () -> { Thread.sleep(5000); });
과제 1. live-study 대시 보드를 만드는 코드를 작성하세요.
package assignment.gitapi;
import org.kohsuke.github.*;
import java.io.IOException;
import java.util.*;
public class Application {
private final String token = "tokenString";
private GitHub github;
public static void main(String[] args){
Application app = new Application();
try {
app.run();
} catch (IOException e) {
e.printStackTrace();
}
}
private void run() throws IOException {
// 연결
connectGitApi();
GHRepository ghRepository = github.getRepository("whiteship/live-study");
// 참여자 이름, 참여 횟수
Map<String, Integer> participant = new HashMap<>();
// 모든 이슈를 가져온다.
List<GHIssue> issues = ghRepository.getIssues(GHIssueState.ALL);
//Find Issue
for (GHIssue issue : issues) {
// 각각의 Issue 에 존재하는 comment 들을 저장.
List<GHIssueComment> commentList = issue.getComments();
// 혹시 모를 유저 중복을 제거하기 위한 Set
Set<String> nameList = new HashSet<>();
addParticipantInSet(commentList, nameList);
// 참여자 명단에서 비교한다.
for (String s : nameList) {
hasParticipantInSet(participant, s);
}
}
printParticipantRate(participant);
}
private void hasParticipantInSet(Map<String, Integer> participant, String s) {
if (!participant.containsKey(s)){
participant.put(s, 1);
} else {
Integer integer = participant.get(s);
participant.put(s, ++integer);
}
}
private void addParticipantInSet(List<GHIssueComment> commentList, Set<String> name) throws IOException {
for (GHIssueComment ghIssueComment : commentList) {
name.add(ghIssueComment.getUser().getLogin());
}
}
private void printParticipantRate(Map<String, Integer> participant) {
participant.forEach((key, value)-> {
double percent = (double) (value * 100) / 18;
System.out.println(key+" : "+String.format("%.2f", percent)+"%");
});
}
private void connectGitApi() throws IOException {
github = new GitHubBuilder().withOAuthToken(token).build();
}
}
package assignment.stack;
public class StackNode {
private int[] elements;
private int head = 0;
private int size = 16;
private int modifyCount = 0;
public StackNode() {
elements = new int[size];
}
public StackNode(int size) {
elements = new int[this.size = size];
System.out.println(this.size);
}
public boolean push(int data){
if (modifyCount >= size){ return false; }
elements[modifyCount] = data;
head = modifyCount;
++modifyCount;
return true;
}
public int pop(){
if (head < 0) { return -1; }
int res = elements[head];
elements[head] = -1;
head--;
return res;
}
public void print(){
for (int index : elements){
if (index == 0 || index == -1){
System.out.println("is Empty");
break;
}
System.out.println(index);
}
}
}
package assignment.queue;
public class ArrayQueue {
private int[] elements;
private int size = 16;
private final int head = 0;
private int modifyCount = 0;
public ArrayQueue() {
elements = new int[size];
}
public ArrayQueue(int size) {
elements = new int[size];
}
public boolean offer(int data){
if (modifyCount >= size){ return false; }
if (data < 0){ return false; }
elements[modifyCount] = data;
++modifyCount;
return true;
}
public int poll(){
int res = elements[head];
int modify = 0;
for (int loop = 1; loop < modifyCount; loop++) {
elements[loop-1] = elements[loop];
modify = loop;
}
elements[modify] = -1;
modifyCount = modify;
return res;
}
public int size() {
int size = 0;
for (int index : elements){
if (index == -1){ break; }
if (index == 0){ break; }
++size;
}
return size;
}
public void print() {
for (int index : elements){
if (index == -1){ break; }
if (index == 0){ break; }
System.out.println(index);
}
}
}
// long과 int를 더하는 경우에는?
long longA = 10l;
int numC = 10;
System.out.println(longA+numC);
// 실제로는 int 가 long으로 Type Conversion이 된 것을 알 수 있다. - 2주차 내용
System.out.println(longA + (long)numC);
// long과 double를 더하는 경우에는?
long longA = 10;
double doubleA = 10.0;
System.out.println(longA+doubleA);
// 실제로는 long 이 double로 Numeric Promotion이 된 것을 알 수 있다.
System.out.println((double)longA + doubleA);
A - B : 뺄셈 연산자
int numA = 10;
int numB = 10;
System.out.println(numA - numB);
int j = numA - numB;
System.out.println(j); // 0 출력
A / B : 나눗셈 연산자
나눗셈 연산과 나머지 연산의 경우 피연산자로 0을 사용하면 Exception이 발생한다.
int numA = 10;
int numB = 10;
System.out.println(numA / numB);
int k = numA / numB;
System.out.println("k = " + k); // 1 출력
A % B : 나머지 연산자
int numA = 11;
int numB = 2;
System.out.println(numA % numB);
int l = numA % numB;
System.out.println("l = " + l); // 1 출력
A * B : 곱하기 연산자
int numA = 11;
int numB = 2;
System.out.println(numA * numB);
int h = numA % numB;
System.out.println("h = " + h); // 22 출력
++N, --N : 전위 증감 연산자
int numC = 10;
numC = --numC;
System.out.println("numC = " + numC);
int numD = 10;
numD = ++numD;
System.out.println("numD = " + numD);
// Decompile
// 전위 증감 연산자는 내부적으로 A = A +- 1; 의 형식을 취하는 것을 알 수 있다.
int numC = 10;
int numC = numC - 1;
System.out.println("numC = " + numC);
int numD = 10;
int numD = numD + 1;
System.out.println("numD = " + numD);
N++, N-- : 후위 증감 연산자
int numE = 10;
System.out.println(numE--);
System.out.println("numE = " + numE);
int numF = 10;
System.out.println(numF--);
System.out.println("numF = " + numF);
// Decompile
// 우선 임시변수를 만들어서 해당 값을 복사한뒤 전달하고 반영된 값을 그 이후에 제공한다.
int numE = 10;
byte var10001 = numE; // 임시변수에 값 복사
int numE = numE - 1; // 변수 연산
System.out.println(var10001); // 임시변수 출력
System.out.println("numE = " + numE); // 연산된 변수를 제공
int numF = 10;
var10001 = numF;
int numF = numF - 1;
System.out.println(var10001);
System.out.println("numF = " + numF);
Wrapper와 Primitive 간의 산술 연산
Wrapper Class* (Integer, Long, Double)와 Primitive Type 연산 시에는 Wrapper Class 피연산자가 Unboxing 되어 연산이 진행되고 다시 Boxing이 되는 등에 성능상 오버헤드가 발생한다.
int numB = 10;
Integer numA = numB; //autoboxing
numA = numA + numB; //unboxing 후 연산 -> 결과 반영 전 다시 autoboxing 진행
그리고 Operand Stack에서 관리되는 Primitive Type과 Heap에서 참조되는 Wrapper Type은 값에 접근하는 시간에 차이가 존재한다. (일반적으로 Wrapper의 Access 시간이 길다.)
Primitive 도 일정 값 이상의 경우, Constant Pool이라는 Stack 외부에 존재하는 공간에 저장된다.*
JVM 설정 중에 Primitive 값의 크기에 대한 설정이 있다고 한다.
즉 프로그램의 환경적인 부분에 따라서 수치나 연산 시간 등이 달라질 수 있다.
비트 연산자?
A & B : AND 연산 ( A와 B의 비트에 대해서 AND 연산을 수행한다.)
//양쪽의 비트가 1이면 1, 0이면 0, 0 과 1 인 경우에는 0을 나타낸다.
int num = 15; // 1111
int nums = 6; // 0110
// 0110 : AND 연산
int i = num & nums;
System.out.println("i = " + i); // 6
A | B : OR 연산 ( A와 B의 비트에 대해서 OR 연산을 수행한다.)
//하나의 비트가 1이면 1, 양쪽의 비트가 0이면 0이다.
int num = 15; // 1111
int nums = 6; // 0110
// 1111 : OR 연산
int i = num | nums;
System.out.println("i = " + i); // 15
A ^ B : XOR 연산 ( A와 B의 비트에 대해서 XOR 연산을 수행한다.)
//하나의 비트가 1이면 1, 양쪽의 비트가 0이면 0, 양쪽의 비트가 1이면 0이다.
int num = 15; // 1111
int nums = 6; // 0110
// 1001 : XOR 연산
int i = num ^ nums;
System.out.println("i = " + i); // 9
A << N : 시프트 연산자 ( A의 비트를 좌측으로 N만큼 이동한다.)
//비트를 좌측으로 N만큼 이동하고 우측에서 N만큼의 영역을 0으로 채우게된다.
int num = 15; // 1111
int nums = 2;
int i = num << nums; // 111100 = 좌측으로 비트를 2칸씩 이동.
System.out.println("i = " + i);
A >> N : 시프트 연산자 ( A의 비트를 우측으로 N만큼 이동한다.)
//비트를 우측으로 N만큼 이동하고 좌측에서 N만큼의 영역을 0으로 채우게된다.
int num = 15; // 1111
int nums = 2;
int i = num >> nums; // 0011 = 우측으로 비트를 2칸씩 이동.
System.out.println("i = " + i);
A >>> N : 부호가 없는 시프트 연산자 ( A의 2진수를 우측으로 비트를 N만큼 이동한다.)
int num = -15; // 11111111111111111111111111110001
int nums = 2;
// 부호를 신경쓰지 않고 모든 비트 값들을 오른쪽으로 이동시킨 후에 왼쪽의 빈 공간은 모두
// 0 으로 채운다.
int i = num >>> nums;
System.out.println("i = " + i); // 1073741820 = 00111111111111111111111111111100
int j = -15 >> nums;
System.out.println("j = " + j); // -4 : 11111111111111111111111111111100
~A : 반전 연산자 ( A 내부의 비트 값을 반전시킨다.)
int num = -15; // 11111111111111111111111111110001
System.out.println(~num); // 14 : 00000000000000000000000000001110
관계 연산자?
A == B : 동일성 비교 ( A와 B가 같다면?)
int numA = 10;
int numB = 10;
boolean isSame = numA == numB; // boolean 값을 반환.
if (isSame){
System.out.println(isSame); // true
}
혹은
if (numA == numB){
System.out.println(isSame); // true
}
A != B : 동일하지 않은 경우 ( A와 B가 같지 않다면?)
int numA = 10;
int numB = 9;
boolean isSame = numA != numB;
if (isSame){
System.out.println(isSame); //true
}
또는
if (numA != numB){
System.out.println(isSame); //true
}
또는
boolean isSame = numA == numB;
if (!isSame){
System.out.println(isSame); //false
}
A > B : 대소 관계 비교 ( A가 B보다 크다면?)
int numA = 10;
int numB = 9;
boolean isSame = numA > numB;
if (isSame){
System.out.println(isSame); //true
}
if (numA > numB){
System.out.println(isSame); //true
}
A >= B : 대소관계 비교 ( A가 B보다 크거나 같다면?)
int numA = 10;
int numB = 10;
boolean isSame = numA >= numB;
if (isSame){
System.out.println(isSame); //true
}
if (numA >= numB){
System.out.println(isSame); //true
}
A < B : 대소관계 비교 ( A가 B보다 작다면?)
int numA = 9;
int numB = 10;
boolean isSame = numA < numB;
if (isSame){
System.out.println(isSame); //true
}
if (numA < numB){
System.out.println(isSame); //true
}
A <= B : 대소관계 비교 ( A가 B보다 작거나 같다면?)
int numA = 10;
int numB = 10;
boolean isSame = numA <= numB;
if (isSame){
System.out.println(isSame); //true
}
if (numA <= numB){
System.out.println(isSame); //true
}
논리 연산자?
조건식 1 && 조건식2 : 조건식1과 조건식 2를 모두 만족한다면?
int numA = 10;
int numB = 10;
int numC = 10;
int numD = 10;
boolean bool = numA == numB && numC < numD; //false
if (bool){
System.out.println(bool);
}else {
**System.out.println(bool);
}
if (numA == numB && numC == numD){
System.out.println(numA == numB && numC == numD); //true
}
조건식1 || 조건식2 : 조건식1 혹은 조건식2를 만족한다면?
int numA = 10;
int numB = 10;
int numC = 10;
int numD = 10;
boolean bool = numA == numB || numC < numD; //true
if (bool){
System.out.println(bool);
}else {
System.out.println(bool);
}
if (numA == numB || numC == numD){
System.out.println(numA == numB && numC == numD); //true
}
! : 논리 반전 연산자 : != 같지않다면?, !< 작지않다면?
int num = 10;
String conn = null;
boolean bool = num != 9;
if (bool){
System.out.println(bool);
}else {
System.out.println(bool);
}
if (conn != null){
System.out.println("true");
}else {
System.out.println("false");
}
JDK Assertion (JDK 1.4+)
이전에 작성된 코드에서 사용된 assert라는 변수들과의 하위 호환성을 위해 기본적으로 비활성화되어 있다.
```java
assert service != null; // true -> 아무 일도 발생하지 않는다.
// false -> AssertionError (Unchecked Exception) 발생
혹은
assert service != null : "Service is Null"; // false 시 추가적으로 메세지를 제공한다.
instanceof
A instanceof B : (공변) 타입 검증 연산자, A가 B의 타입 혹은 하위 구현체인지 판단한다.
Reference Type 만 사용 가능하다.
public static void main(String[] args) {
InstanceofExample example = new InstanceofExample();
example.run();
}
public void run() {
SomeClass someClass = new SomeClass();
SomeClasz someClasz = new SomeClasz();
SomeClassChild someClassChild = new SomeClassChild();
typeCheck(someClass); // is SomeClass
typeCheck(someClasz); // is SomeClasz
typeCheck(someClassChild); // is SomeClass
}
public void typeCheck(Object obj){
if (obj instanceof SomeClass){
System.out.println("is SomeClass");
}else if (obj instanceof SomeClasz){
System.out.println("is SomeClasz");
}
}
class SomeClass {
}
class SomeClassChild extends SomeClass{
}
class SomeClasz {
}
대입 연산자? (assignment(=) operator)
Primitive 변수에 값을 할당하기 위해 사용하거나 Reference의 참조 값을 할당하기 위해 사용한다.
Arrow operator? ( (parameter list) -> lambda body )
Java 8에 추가된 lambda 식을 지원하기 위해 사용되는 연산자이다.
// 이러했던 구문을
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Hello!");
}
};
// 이렇게 축약할 수 있다.
// 하나의 식, 로직을 가지고 있다면 { } block 과 return도 생략 가능하다.
Runnable runnable = () -> System.out.println("Hello!");
// 그렇지 않다면 이런식으로 작성해야한다.
Runnable runnable = () -> {
System.out.println("Hello!");
helloLogic();
**};**
3항 연산자? ( Ternary Operator : 변수 = (조건)? true 인 경우 : false 인 경우)
삼항 연산자는 피연산자 3개를 사용하며, if-then-else 명령문의 축약형이라고 할 수 있다.
int num = 10;
String result;
if(num == 10){
result = "true";
System.out.println("result = " + result);
}else {
result = "false;
System.out.println("result = " + result);
}
result = (num == 10) ? "true" : "false";
System.out.println("result = " + result);
연산자 우선순위?
수식 내에 여러 연산자가 함께 등장할 때, 어느 연산자가 먼저 처리될 것인가를 결정합니다.
( ) 등으로 우선순위, 결합 방향에 따른 연산자의 처리 순서를 변경할 수도 있습니다.
연산자의 결합 규칙?
수식 내에 우선순위가 같은 연산자가 둘 이상 있을 때, 먼저 어느 연산을 수행할 것인가를 결정합니다.
int numA = 5;
int numB = 2;
int numC = 2;
// +, - 의 우선 순위가 동일하다.
// 결합 방향에 따라서 왼쪽부터 오른쪽으로 진행하게 된다.
int res = numA + numB - numC;
Java 13의 switch 연산자?
기존 switch 문법으로 만든 요일 반환식 (윤년을 앞선 로직에서 체크했다고 가정.)
public static String monthCheck(int num){
int days = 0;
switch (num) {
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 = -1;
};
return "입력하신 달은 "+days+"일 입니다.";
}
Java 12에서 switch는
case 라벨을 쉼표로 구분하여 사용하게끔 문법을 지원하게 되었다.
break을 통해 값을 반환할 수 있게끔 되었다.
public static String monthCheck(int num){
int days = switch (num) {
case 1, 3, 5, 7, 8, 10, 12 :
break 31;
case 4, 6, 9, 11 :
break 30;
case 2 :
break 28;
default:
break -1;
};
return "입력하신 달은 "+days+"일 입니다.";
}
혹은 이와 같이 람다 식을 사용할 수 있게 되었다.
public static String monthCheck(int num){
int days = switch (num) {
case 1, 3, 5, 7, 8, 10, 12 -> 31;
case 4, 6, 9, 11 -> 30;
case 2 -> 28;
default -> -1;
};
return "입력하신 달은 "+days+"일 입니다.";
}
Java 13에서 switch는
기존에 사용하던 break이라는 키워드를 yield로 대체(확장) 하게 되었다.
public static String monthCheck(int num){
int days = switch (num) {
case 1, 3, 5, 7, 8, 10, 12 :
yield 31;
case 4, 6, 9, 11 :
yield 30;
case 2 :
yield 28;
default:
yield -1;
};
return "입력하신 달은 "+days+"일 입니다.";
}
또는
public static String monthCheck(int num){
int days = switch (num) {
case 1, 3, 5, 7, 8, 10, 12 -> 31;
case 4, 6, 9, 11 -> 30;
case 2 -> 28;
default -> {
System.out.println("잘못 입력했습니다.");
yield -1;
}
};
return "입력하신 달은 "+days+"일 입니다.";
}