스터디할래 - 4주차 과제: 제어문

스터디할래 - https://github.com/whiteship/live-study

목표

자바가 제공하는 제어문을 학습하세요.

 

학습할 것

선택문

반복문

 

 

  • 선택문

자바는 선택논리의 제공을 위해 if-else, switch문을 제공한다. 일반적으로 if-else 문을 조건문으로 나누기도 하지만, 제어문 학습에 선택문과 반복문을 학습하라 하였으므로 조건문을 선택 문이라 간주하고 작성하도록 하겠다.

  • if-else 문

if

if문은 조건식의 결과에 따라 블록의 실행 여부가 결정된다. if 문의 형식과 흐름을 도식화하면 다음과 같다.

If문 형식

if문의 괄호 안에 조건식이 들어가며 조건식이 참 일 경우 중괄호{ } 안의 내용이 실행된다.

중괄호 안의 내용이 한줄이라면 다음과 같이 중괄호를 생략할 수 있다.

 

실행문이 한줄 일 경우 중괄호 생략

 

 

int score = 81;
if (score > 90) {
    System.out.println("A");
}
if (score > 80) {
    System.out.println("B");
}

Output:
B

코드 설명: score는 81로 첫번째 if 문의 조건식인 'score > 90'을 만족하지 않으므로 해당 조건문은 실행되지 않는다.

두 번째 if문의 조건식인 'score > 80'을 만족하므로 실행문인

System.out.println("B");'가 실행되어 B를 출력한다.

 

 

if-else 

if문은 else 블록과 함께 사용되어 조건식의 결과에 따라 실행 블록을 선택할 수 있다.

if문의 조건식이 참(true)이라면 if 문의 실행문이 실행되며, 거짓(false) 일 경우 else 문의 실행문이 실행된다.

if-else 문의 형식과 실행 흐름은 다음과 같다.

 

if-else 문 흐름

 

 

int score = 81;
if (score > 90) {
    System.out.println("A");
} else {
    System.out.println("F");
}

Output:
F

코드 설명: score 는 81로 if 문의 조건식을 만족하지 않으므로 else 문의 내용이 실행되어 "F"를 출력한다.

 

 

 

if-else if -else 

조건문이 여러 개 존재하는 if문도 있다. 처음 if문의 조건식이 false일 경우, 다른 조건식의 결과에 따라 실행 블록을 선택할 수 있는데, if 블록의 끝에 else if 문을 붙이면 된다. else if문의 갯수는 제한이 없으며, 여러 개의 조건식 중 true인 블록만 실행되고 전체 if문을 탈출한다. else if문의 마지막 블록으로 else 문을 추가할 수 있으며, if()와 else if()가 모두 거짓 일 경우 실행된다.

다음은 if - else if - else 문의 실행 흐름을 나타낸다.

 

if - else if - else문 흐름

조건식 1을 만족하면 if 문의 내용이 실행된다. 조건식 1을 만족하지 않을 경우, else if(조건식2) 의 조건식2를 검사하며, 조건식2가 참 일 경우 else if 문의 내용이 실행되어 거짓일 경우, else 문의 내용이 실행된다. 조건식3을 추가할 수도 있는데, else if(조건식2) 닫은 중괄호 옆에 또 다른 else if문을 추가하여 조건식을 추가할 수 있다.

 

 

 int score = 81;
 if (score > 90) {
     System.out.println("A");
 } else if(score >80 && score <=90 ){
     System.out.println("B");
 } else {
     System.out.println("F");
 }
 
 Output:
 B

코드 설명: score는 81로 if문의 조건식을 만족하지 않고, else if 문의 조건식을 확인한다. 조건식이 score > 80이면서 score <= 90 의 조건을 만족하므로 B를 출력하며, else 문은 실행되지 않고 if문을 탈출한다.

 

 

  • switch 문

switch문은 if문과 마찬가지로 조건 제어문이다. 하지만 switch문은 if문처럼 조건식이 true일 경우에 블록 내부의 실행문을 실행하는 것이 아니라, 변수가 어떤 값을 갖느냐에 따라 실행문이 선택된다. if문은 조건식의 결과가 true 혹은 false 2가지 경우 밖에 없기 때문에 경우의 수가 늘어날 경우 else if가 늘어나 코드가 복잡해지는 반면, switch문은 변수의 값에 따라 실행문이 결정되기 때문에 같은 기능의 if문보다 코드가 간결해지는 장점이 있다.

switch문의 실행 흐름은 다음과 같다.

 

switch문 실행 흐름

 

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int dice = scanner.nextInt();

        switch (dice) {
            case 1:
                System.out.println("주사위 숫자는 1입니다");
                break;
            case 2:
                System.out.println("주사위 숫자는 2입니다");
                break;
            case 3:
                System.out.println("주사위 숫자는 3입니다");
                break;
            case 4:
                System.out.println("주사위 숫자는 4입니다");
                break;
            case 5:
                System.out.println("주사위 숫자는 5입니다");
                break;
            case 6:
                System.out.println("주사위 숫자는 6입니다");
                break;
            default:
                System.out.println("유효한 숫자가 아닙니다");
        }
        System.out.println("입력한 주사위 숫자는 : " + dice + "입니다.");
        scanner.close();
    }
}
/* example 1 */
Input: 
1
Output:
주사위 숫자는 1입니다

/* example 2 */
Input:
7
Output:
유효한 숫자가 아닙니다

코드 설명: scanner로 Int 변수를 입력받아서, switch 문에서 입력 값에 따라 실행문이 결정된다. example1을 보면, 1을 입력했을 때, 'case 1: ' 의 실행문이 실행되는 것을 볼 수 있으며 example2에서는 7을 입력하였고 case 문에 해당하는 값이 없어 default 문 내용을 실행하는 것을 볼 수 있다. 

 

 

 

 

  • 반복문

반복문은 코드를 반복적으로 실행할 때 사용되며, 반복문의 종류로는 for 문, while 문, do-while문이 있다. for문과 wihle문은 서로 변환이 가능하기 때문에 어느 것을 선택해도 좋지만, for문은 반복 횟수를 알고 있을 때 주로 사용하고, while문은 조건에 따라 반복할 때 사용한다. while문과 do-while문의 차이는 while문은 조건을 검사하고, 조건을 만족하지 않으면 실행되지 않지만, do-while은 '선 실행 후 검사' 라 할 수 있다.

 

  • for 문

for문은 똑같은 실행문을 반복적으로 실행해야 할 경우 사용한다. for문의 실행 흐름을 나타내면 다음과 같다.

 

for문 실행 흐름

for문이 처음 실행될 때 ①초기화 식이 실행되고, ②조건식을 평가해서 true면 ③실행문을 실행시키고, false면 for문 블록을 실행하지 않고 for문은 종료된다. 실행문이 실행된 후 ④증감식이 실행되고 다시 조건식을 평가하고 조건식을 만족하지 않으면 for문은 완전히 종료 된다. 만약 for문의 조건식이 빈칸이거나, for문의 조건식이 항상 참 일 경우, 무한 루프가 발생한다.

 

public class Main {
    public static void main(String[] args) {
        int sum1To100 = 0;
        for (int i =1; i <= 100; i++) {
            sum1To100 += i;
        }
        System.out.println("1부터 100까지 합은: " + sum1To100 + " 입니다. ");
    }
}

Output:
1부터 100까지 합은: 5050입니다.

코드 설명: 1부터 100까지의 합을 구하는 코드로 sum1To100의 변수를 0으로 초기화하고, for문을 반복하며 초기화식

'int i = 1'로 i를 1로 초기화 후, 조건식 'i <= 100'을 검사한다. i는 1이므로 조건식을 만족하고 실행문인 sum1To100에 i를 더하는 코드를 실행한다. 이후 증감식을 실행하여 i는 2가 되고, 다시 조건식을 검사하는 작업을 반복한다. 

계속 반복되고 i가 101이 됐을 때 조건식을 만족하지 않으므로 for문은 종료되며 for 문 이후 코드인 1부터 100까지의 합을 출력하는 코드를 출력한다.

 

 

  • while 문

for문이 정해진 횟수만큼 반복한다면, while문은 조건식이 true 일 경우에 계속 반복되는 특징이 있다. while문의 실행 흐름은 다음과 같다.

while문 실행 흐름

while문이 처음 실행되면 조건식을 평가한다. 조건식이 true 일 경우, 실행문이 실행되고 다시 조건식을 평가한다. 조건식이 거짓 일 때까지 반복되며 조건식을 만족하지 않으면 while문은 종료된다. 만약 wihle문의 조건식이 항상 참일 경우, for문과 마찬가지로 무한루프가 발생한다. 

 

public class Main {
    public static void main(String[] args) {
        int sum1To100 = 0;
        int i = 1;
        while(i <= 100) {
            sum1To100 += i;
            i++;
            // == sum1To100 += i++; 은 같은 결과를 출력한다.
        }
        System.out.println("1부터 100까지 합은: " + sum1To100 +  "입니다.");
    }
}

Output:
1부터 100까지 합은: 5050입니다.

코드 설명: for문의 1부터 100까지 구하는 코드를 while문으로 변환한 코드이다. 같은 결과를 출력하며 while문의 조건식을 만족할 때까지 i의 값을 증가시키며 합을 누적하고 조건식을 만족하지 않을 경우 wihle문을 종료하고 1부터 100까지의 합을 출력한다.

 

 

  • do while 문

do-while문은 조건식에 의해 반복 실행한다는 점에서 while문과 동일하지만, while문 실행하기 전 조건식을 검사하는 반면 do-while문은 조건식을 검사하기 전에 실행하고 나서 조건식을 검사한다는 특징이 있다.  do-while문의 실행 흐름은 다음과 같다.

 

do-while문 실행 흐름

do-while문은 실행문을 먼저 실행하고, 조건식을 검사한다. 조건식이 true일 경우 실행문을 다시 실행시킨다. 실행문이 실행되고 조건식을 검사하며, 조건식이 거짓일 경우 do-while문은 종료된다. do-while문의 주의할 점으로는 while(조건식) 뒤에 반드시 세미콜론(;)을 붙여야 한다.

 

public class Main {
    public static void main(String[] args) {
        int sum1To100 = 0;
        int i = 1;
        do {
            sum1To100 += i;
            i++;
        } while (i <= 100);
        System.out.println("1부터 100까지 합은: " + sum1To100 +  "입니다.");
    }
}

Output:
1부터 100까지 합은: 5050입니다.

코드 설명: while문의 코드와 동일한 결과를 출력하지만 do while문은 첫 실행을 조건식을 검사하기 전에 합을 누적하며 변수를 증가시키고 나서 조건식을 검사한다. 이후 동작과 결과는 while문의 예제 코드와 동일하다.

 

 

  • break, continue

break문은 반복문과 선택문의 동작을 의도적으로 중단시킬 때 사용한다. 

continue문은 반복문에서 사용되며 for문에서는 증감식 또는 while, do-while문에서는 조건식으로 이동한다. 

 

public class Main {
    public static void main(String[] args) {
        int i = 1;
        int sumOdd = 0;
        while (true) {
            if (i == 100) {
                break;
            }
            if (i % 2 == 0) {
                i++;
                continue;
            }
            sumOdd += i;
            i++;
        }
        System.out.println("1부터 100까지 홀수의 합은 :" + sumOdd + " 입니다. ");
    }
}

코드 설명: 1부터 100까지 홀수의 합을 구하는 예제로 while문의 조건식은 항상 참이므로 무한 루프를 돌지만, if 문의 조건식 i가 100 일 경우 break문을 선언하여 i가 100이 될 경우 while문을 탈출할 수 있으며 i가 100이 되기 전까지 

i가 짝수 일 경우 i의 값을 증가시키고 다시 while문의 조건식으로 이동한다. i가 홀수라면  값을 누적하고, i값을 증가시킨다. i가 100이 될 때 while문은 종료되고, 1부터 100까지 홀수의 합을 출력한다.

 

 

 

과제


과제 0. JUnit 5 학습하세요.

  • 인텔리J, 이클립스, VS Code에서 JUnit 5로 테스트 코드 작성하는 방법에 익숙해 질 것.

  • 이미 JUnit 알고 계신분들은 다른 것 아무거나!

  • 더 자바, 테스트 강의도 있으니 참고하세요~

 

 

 

Junit5에 대해 자세히, 완벽히 알고 있지는 않지만 생초보 수준은 아니라 생각하고 Mockito에 대해 학습하고 싶기도하여 또 다른 테스트 프레임워크인 Mockito에 대해 정리하고자 한다.

 


 

Mockito란?

 

Mockito는 자바의 단위 테스트 프레임워크로 목 객체(가짜 객체)를 만들어 동작을 지정하고 테스트 대상 로직이 제대로 수행 되었는지 테스트할 수 있다. 백기선님의 설명에 따르면 외부 API의 동작을 검증하기 위해 사용한다고 하셨다.

 

 

의존성 받아오기

search.maven.org/artifact/org.mockito/mockito-core/3.6.28/jar

 

Maven Central Repository Search

 

search.maven.org

[maven]

  • pom.xml에 depdendency 추가
  • springboot starter web은 mockito의 의존성을 받아온다. 따로 추가 할 필요 x

 

[예제 코드 실행 시켜보기]

개념과 용어을 정리하기 전 Mockito 공식 홈페이지 의 예제 코드를 실행해보자.

 

 

now you can verify interactions(상호 작용[동작]을 검증 할 수 있다.) 

 

코드 설명: sample 메서드의 mock()을 사용하여 List 클래스의 목 객체를 생성한다. list에 "one"을 추가하고 list를 비우는 동작을 수행하였다.

 

 

 

 

and stub method calls( 스텁 메서드를 호출 할 수 있다)

 

코드 설명: 연결리스트의 첫번째 원소로 "first"를 넣고 반환하도록 설정하였다. 이 후 첫번째 원소를 출력하면 "first"를 출력하지만 다른 원소를 출력하면 null을 반환하는 것을 확인 할 수 있다.

 

 

주요 메서드 및 어노테이션

 

  • mock() / @Mock
    • 목 객체를 생성한다
    • 선택적으로 Answer / MockSettings를 통해 작동 방식을 지정
    • when() / given() 등의 모의 동작을 지정 할 수 있음
    • 제공된 답변이 필요에 맞지 않으면 답변 인터페이스를 확장하여 직접 작성 할 수 있음

 

  • spy() / @Spy
    • 부분적인 목킹을 실행하며, 실제 메서드가 호출되지만 여전히 검증과 스터빙이 가능함

 

  • @InjectMocks
    • @Spy 또는 @Mock 어노테이션이 달린 필드를 자동 주입함

 

  • verify()
    • 주어진 인자로 메서드가 호출되었는지 확인
    • 유연한 인자 일치를 사용할 수 있음(예: any() 사용)
    • 또는 @Captor를 대신 사용하여 호출된 인수 캡처

 

 

 

과제 1. live-study 대시 보드를 만드는 코드를 작성하세요.

  • 깃헙 이슈 1번부터 18번까지 댓글을 순회하며 댓글을 남긴 사용자를 체크 할 것.

  • 참여율을 계산하세요. 총 18회에 중에 몇 %를 참여했는지 소숫점 두자리가지 보여줄 것.

  • Github 자바 라이브러리를 사용하면 편리합니다.

  • 깃헙 API를 익명으로 호출하는데 제한이 있기 때문에 본인의 깃헙 프로젝트에 이슈를 만들고 테스트를 하시면 더 자주 테스트할 수 있습니다.

과제 1

구현 코드 링크: github.com/rshak8912/studyhalle/tree/master/src/main/java/me/study/studyhalle/week4/assignment1

 

 

과제 2, 3, 4 테스트 코드 동작 확인(5는 시간적인 여유가 있다면 추후에..)

 

 

 

과제 2. LinkedList를 구현하세요.

  • LinkedList에 대해 공부하세요.

  • 정수를 저장하는 ListNode 클래스를 구현하세요.

  • ListNode add(ListNode head, ListNode nodeToAdd, int position)를 구현하세요.

  • ListNode remove(ListNode head, int positionToRemove)를 구현하세요.

  • boolean contains(ListNode head, ListNode nodeTocheck)를 구현하세요.

과제 2

구현 코드 링크:

github.com/rshak8912/studyhalle/tree/master/src/main/java/me/study/studyhalle/week4/assignment2

테스트 코드 링크: github.com/rshak8912/studyhalle/tree/master/src/test/java/me/study/studyhalle/week4/assignment2

 

 

 

과제 3. Stack을 구현하세요.

  • int 배열을 사용해서 정수를 저장하는 Stack을 구현하세요.

  • void push(int data)를 구현하세요.

  • int pop()을 구현하세요.

과제 3

구현 코드 링크:

github.com/rshak8912/studyhalle/tree/master/src/main/java/me/study/studyhalle/week4/assignment3

테스트 코드 링크: github.com/rshak8912/studyhalle/tree/master/src/test/java/me/study/studyhalle/week4/assignment3

 

 

 

 

과제 4. 앞서 만든 ListNode를 사용해서 Stack을 구현하세요.

  • ListNode head를 가지고 있는 ListNodeStack 클래스를 구현하세요.

  • void push(int data)를 구현하세요.

  • int pop()을 구현하세요

과제 4

구현 코드 링크:

github.com/rshak8912/studyhalle/tree/master/src/main/java/me/study/studyhalle/week4/assignment4

테스트 코드 링크:

github.com/rshak8912/studyhalle/blob/master/src/test/java/me/study/studyhalle/week4/assignment4/ListNodeStackTest.java

 

 

과제 5. Queue를 구현하세요. (optional) 

  • 배열을 사용해서 한번

  • ListNode를 사용해서 한번.

 

References

이것이 자바다(한빛미디어, 신용권)
javadoc mockito
더 자바, 애플리케이션을 테스트하는 다양한 방법 - Mockito 참조
스택
위키피디아 Mockito