본문 바로가기
java-liveStudy

4주차 과제. 제어문 + 과제

by 에드박 2020. 12. 4.

학습할 것

선택문
반복문

과제

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

  • 인텔리J, 이클립스, VS Code에서 JUnit 5로 테스트 코드 작성하는 방법에 익숙해 질 것.
  • 이미 JUnit 알고 계신분들은 다른 것 아무거나!
  • 더 자바, 테스트 강의도 있으니 참고하세요~

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

  • 깃헙 이슈 1번부터 18번까지 댓글을 순회하며 댓글을 남긴 사용자를 체크 할 것.
  • 참여율을 계산하세요. 총 18회에 중에 몇 %를 참여했는지 소숫점 두자리가지 보여줄 것.
  • Github 자바 라이브러리를 사용하면 편리합니다.
  • 깃헙 API를 익명으로 호출하는데 제한이 있기 때문에 본인의 깃헙 프로젝트에 이슈를 만들고 테스트를 하시면 더 자주 테스트할 수 있습니다.

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

  • LinkedList에 대해 공부하세요.
  • 정수를 저장하는 ListNode 클래스를 구현하세요.
  • ListNode add(ListNode head, ListNode nodeToAdd, int position)를 구현하세요.
  • ListNode remove(ListNode head, int positionToRemove)를 구현하세요.
  • boolean contains(ListNode head, ListNode nodeTocheck)를 구현하세요.

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

  • int 배열을 사용해서 정수를 저장하는 Stack을 구현하세요.
  • void push(int data)를 구현하세요.
  • int pop()을 구현하세요.

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

  • ListNode head를 가지고 있는 ListNodeStack 클래스를 구현하세요.
  • void push(int data)를 구현하세요.
  • int pop()을 구현하세요.

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

  • 배열을 사용해서 한번
  • ListNode를 사용해서 한번

제어문 : 실행 순서를 변경시키거나 또는 조건에 따라 실행해야할 명령문을  제어하는데 사용하는 문장

 

선택문 : 특정 조건이 참인 경우에만 문장을 실행하기 위해 사용

→ if , if ~ else , switch

 

반복문 : 조건식이 만족하는 동안 반복적으로 문장을 실행하기 위해 사용

→ for, while, do-while

 

제어문은 모두 중첩해서 사용이 가능합니다.

ex) for문 안에 for 문, if문 안에 for문, while문 안에 for문

 


선택문

조건식의 연산결과에 따라 실행할 문장을 제어할 수 있습니다.

  • if
  • switch

 

저는 if 를 조건문으로 부르고 switch는 선택문으로 알고있었습니다.

정리하면서 생각해보니 if 도 switch도 결국은 실행할 문장을 조건에 따라 선택 하는것이므로 조건문, 선택문을 따로 분리할 필요는 없다고 생각했습니다. (선장님 이게 맞나요? ㅠㅠ)

 

[ if, if ~ else , if ~ else if]

 

if 문은 조건식이 참이면 코드 블럭 안에 명령어를 실행합니다.

 

if문의 종류

  • if 문
  • if ~ else 문
  • if ~ else if 문
if ( 조건식 ) {
    조건식이 참일 때 실행할 문장
}

if ( 조건식 ) {
    조건식이 참일 때 실행할 문장
} else {
    조건식이 거짓일 때 실행할 문장
}

if ( 조건식1 ) {
    조건식1이 참일 때 실행할 문장
} else if ( 조건식2 ) {
    조건식2가 참일 때 실행할 문장
}

if 문

  • 조건식이 참이면 중괄호 내부의 명령어를 실행합니다.

 

 

if 문은 위의 예시처럼 다양하게 사용할 수 있습니다. true일 때는 "hello java!" 가 출력 됐지만 false일 때는 문장이 실행되지 않은걸 볼 수 있습니다.

 

if 문은 코드 블럭 '{ }' 안에 문장이 한문장 일 때 코드 블럭을 생략할 수 있습니다. (예시 중 3번째 if)

 

예시 처럼 코드 블럭을 어디에 놓을지는 코딩 스타일에 따라 다르지만 Google Java Style Guide 에서는

가장 첫번째 예시를 코드 컨벤션으로 하고있습니다.

 

if ~ else 문

  • if문에 else 블럭을 추가해서 if문의 조건식이 참(true)이 아닐 때 else블럭의 문장을 수행합니다.

 

if ~ else if 문

  • 여러개의 조건식이 필요한 경우 if ~ else if 문을 사용합니다.

 

 

if 문은 조건식을 만족하면 아래의 선택문은 실행되지 않고 생략됩니다.

 

따라서 조건식의 순서에 주의하셔야 합니다.

 

잘못된 순서의 선택문 코드

점수는 변화가 없지만

myScore >= 70 보다 myScore >= 60 의 조건식이 위로 가면 학점은 D 가 되버립니다.

 

switch 문

  • switch문은 경우의 수가 많을 때 사용하면 좋습니다.
  • switch문은 if문보다 속도도 빠르고 표현도 간결하여 알아보기 쉬운 장점이 있습니다.
  • 제약조건이 있음

switch 문의 제약조건

  • 조건식의 결과값이 정수여야합니다. (JDK 1,7 부터는 문자열 상수도 가능!)
  • case문의 값이 중복되지 않아야합니다.
switch (조건식) {
    case 값1 :
        조건식과 값1이 일치할 때 실행할 문장
        break;
    case 값2 :
        조건식과 값2가 일치할 때 실행할 문장
        break;
    ...
    case 값 :
        조건식과 값이 일치할 때 실행할 문장
        break; 
    default :
        조건식과 일치하는 값이 없을 때 실행할 문장
}

 

 

 

각 case의 마지막 문장에는 break를 꼭 붙여줘야 합니다.

break문은 case문의 영역을 구분하는 역할을 하고 해당 조건식을 종료하는 역할을 합니다.

 

반복문

  • for
  • for each
  • while
  • do-while

반복문은 어떤 작업을 반복적으로 수행되도록 할 때 사용합니다.

 

for문

  • 반복 횟수를 알고 있을 때 사용하기 적합합니다.
  • 위의 3가지 반복문중 가장 자주 사용되는 반복문으로 구조가 복잡해서 코드를 작성하는데 오타가 많이 발생하지만 반복문의 횟수, 조건이 직관적으로 보여서 좋습니다.

 

for (초기화 ; 조건식 ; 증감식 ;) {
    반복 수행할 문장
}

초기화 : 반복문에서 사용할 변수를 초기화 합니다.
조건식 : 언제까지 반복할지 조건식을 작성합니다.
증감식 : 한번 반복할 때마다 변수의 변경을 담당합니다.
  • for문은 다음과 같은 순서로 동작합니다.

1. 변수를 초기화(최초 시작시에만)

2. 조건식을 연산

3. 조건식이 거짓이면 종료, 참이면 for문 안의 명령문을 실행

4. 증감식을 실행

5. 조건식을 연산

6. 조건식이 거짓이 될 때 까지 2번 ~ 5번을 반복합니다.

 

for 문의 실행순서

 

for 문을 이용해 숫자 0부터 4까지 출력하는 반복문 입니다.

 

변수 i를 0으로 초기화 하고 반복문을 한번 실행할 때마다 i 를 1씩 증가시켜갑니다.

변수 i가 5가 되는 순간 조건식이 거짓이 되어 for문이 종료됩니다.

 

for문도 실행문이 한문장일 때 중괄호 생략이 가능하지만 생략 하지 않고 중괄호를 사용하는 것이 직관적입니다.

 

for each문

  • 배열을 반복문에서 사용해야 할 때 for each문을 사용하면 편리합니다. 
  • for each문은 배열의 첫번째 요소부터 하나씩 가져와서 변수로 사용할 수 있습니다.

 

for (요소를 담을 타입과 변수선언 : 배열) {
    반복 수행할 문장
}

for each문을 이용해서 numbers 의 모든 요소를 출력하는 반복문 입니다. 배열의 처음부터 마지막 요소까지 진행하고나면 반복문을 종료합니다.

while문

  • while 문은 if문 처럼 조건식과 중괄호로만 표현하지만 while문은 조건식이 참인동안 계속해서 반복 실행합니다.
  • 조건식이 계속 참이 되는 경우 반복문을 무한히 실행하는 무한루프가 될 수 있으므로 조건식을 주의해서 설정해야 합니다.

 

while (조건식) {
    반복 수행할 문장
}

while문 실행 순서

1. 조건식 연산

2. 조건식이 참이면 문장 실행, 거짓이면 종료

3. 문장을 실행하고 다시 조건식으로

4. 조건식 연산 ( 조건식이 거짓일 때까지 1 ~ 3 반복)

 

 

while 문을 이용해서 num이 5보다 작을 때 num을 출력하는 반복문 입니다.

 

내부적으로 num을 1씩 증가시키면서 반복문을 돌다가 num이 5보다 커지는 순간 조건식에서 거짓을 반환하여 반복문을 빠져나옵니다.

 

do-while 문

  • while 문과 기본적인 구조는 비슷하지만 조건식과 실행 블럭의 순서를 바꿔놓은 것입니다.
  • do-while 문은 최소 한번의 실행을 보장하는 반복문 입니다.
do {
    반복 실행할 문장
} while ( 조건식 );  <--- do-while문은 끝에 ';' 을 붙여야합니다.

보통 사용자의 입력을 받을 때 많이 사용하는 반복문 입니다.

 

예시에서 처럼 while(false) 라도 한번은 실행되는것을 출력결과를 통해 확인할 수 있습니다.

 

두번째 반복문은 사용자에게 숫자를 입력받아서 출력하는 반복문입니다.

입력한 숫자가 10이 되면 반복문을 종료합니다.

 

break 문

  • switch 에서 break를 사용하듯이 반복문에서도 break를 사용할 수 있습니다.
  • break를 사용하면 자신과 가장 가까이 있는 반복문을 벗어납니다.
  • 주로 if 문과 함께 사용되어 조건식을 만족하면 반복문을 벗어나도록 합니다.

while(true) 로 계속 반복문을 돌리며 i를 1씩 증가시키다 if 문에서 i가 5보다 클 때 break문을 사용해 반복문을 종료하는 예제 입니다.

 

continue 문

  • 반복문 내에서만 사용 가능
  • 반복문 실행 도중 continue 문을 사용하면 반복문의 마지막으로 이동한 뒤 다시 반복하여 실행합니다.

1부터 10까지 출력하는 반복문에서 3의 배수일때는 continue 문을 호출하는 반복문 입니다.

 

i를 3으로 나눈 나머지가 0일때 continue로 인해서 밑의 출력문을 실행하지 않고 반복문의 처음으로 돌아갑니다.

 

이름 붙은 반복문 

  • break 문은 가장 가까운 반복문을 빠져나오기 때문에 여러개의 반복문이 중첩된 경우는 break문 하나로 전체를 빠져나올 수 없습니다.
  • 반복문에 이름을 붙여주고 break 문 뒤에 그 이름을 붙이면 하나 이상의 반복문을 빠져나올 수 있습니다.
  • continue도 똑같이 사용이 가능합니다.
  • continue에 이름을 붙이면 해당 이름의 반복문의 끝부분으로 이동하여 다시 반복을 시작합니다.
반복문 이름 :
    for (조건식) {
        for (조건식) {
             break 반복문 이름;
        }
}
반복문 이름 :
    continue (조건식) {
        for (조건식) {
            break 반복문 이름;
        }
}

 

바깥 반복문에 loop1 이라는 이름을 붙여주고 내부의 중첩 반복문에서 break loop1이 실행되면 바깥의 반복문이 반복을 종료하면서 내부의 모든 반복문도 함께 종료됩니다.

 

내부 반복문에서 j는 0부터 4까지 반복해야 하지만 j가 1일 때 continue loop1 을 실행하기 때문에

loop1 을 붙인 반복문의 마지막 까지 이동합니다.

 


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

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

JUnit5 VS JUnit4

JUnit4

  • 하나의 jar 에 전체기능이 들어가 있어서 특정 기능만 필요해도
  • 라이브러리 전체를 가져와야 합니다.
  • 즉, junit 라이브러리만 정의해주면 됩니다. 
  • Java 5버전 이상부터 사용가능

JUnit5

  • 3개의 모듈로 나눠져 있습니다.
  • JUnit5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
  • 자바의 람다 기능을 사용할 수 있습니다.
  • Java 8버전 이상부터 사용가능

JUnitPlatform
- JVM 환경에서 테스트 프레임웍을 수행
- TestEngine API가 정의되어있음

 

JUnit Jupiter
- 테스트를 작성하기 위해 추가된 확장 기능들이 포함되어 있음

JUnit Vintage
- JUnit3, JUnit4를 JUnit5 플랫폼에서 실행할 수 있게 해줍니다.

- 이전 버전과의 호환성

 

JUnit5의 Annotations

 

  • @Test : 테스트임을 나타내는 메서드
  • @TestFactory : 동적 테스트임을 나타내는 메서드
  • @ParameterizedTest : 
  • @BeforeAll : 모든 테스트가 실행되기 전 1번만 실행됩니다.
  • @AfterAll : 모든 테스트가 실행된 후 1번만 실행됩니다.
  • @BeforeEach : 각 테스트가 실행되기 전 1번씩 실행됩니다.
  • @AfterEach : 각 테스트가 실행된 후 1번씩 실행됩니다.
  • @Order : 정수값을 우선 순위로 테스트합니다. [ 실행 순서 예시 : Order(1) -> Order(2) -> Order(3) ... ]
  • @DisplayName : 테스트 클래스 또는 테스트 메서드의 이름을 지정합니다.
  • @Disabled : 테스트 클래스 또는 메서드를 비활성화할 수 있다. (JUnit4의 @Ignore와 동일)
  • @Tag : 클래스 또는 메서드 레벨에서 필터링 테스트를 위한 태그를 선언합니다.
  • @ExtendWith : 사용자 지정 확장을 선언적으로 등록하는데 사용합니다.

JUnit5 의 Assertions

assertEquals(A, B) : 매개변수 A,B가 같은지 비교해서 같으면 통과

assertTrue(A) : A가 true면 통과

assertThrows(A,B) : A의 예외가 B에서 발생하면 통과

assertAll() : 테스트를 여러개 구현할 수 있으며 기존의 assertEqual 과 같은 메서드는 하나가 실패하면 이후의 메서드도 실행하지 않았지만  assertAll을 사용하면 하나가 실패하더라도 모든 메서드를 실행합니다. 또한 MultipleFailuresError 를 발생시켜 어떤 테스트가 실패했는지 알기 쉽게 해줍니다.

JUnit5 익숙해지기

 


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

 

import org.kohsuke.github.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;



public class IssueReplyUser {
    private static final String repositoryName = "whiteship/live-study";
    private static final String myPersonalToken = "personalToken";

    GitHub gitHub;

    public void start() throws IOException {

        connectGithubApi();

        GHRepository ghRepository = gitHub.getRepository(repositoryName);

        Map<String, Integer> participantMap = new HashMap<>();

        List<GHIssue> issues = ghRepository.getIssues(GHIssueState.ALL);

        for (GHIssue issue : issues) {
            List<GHIssueComment> commentList = issue.getComments();

            for (GHIssueComment ghIssueComment : commentList) {
                String participant = getCommentUserName(ghIssueComment);
                addParticipantMap(participantMap, participant);
            }
        }
        printDashboard(participantMap, issues.size());
    }

    private void connectGithubApi() throws IOException{
        gitHub = new GitHubBuilder().withOAuthToken(myPersonalToken).build();
    }

    private String getCommentUserName(GHIssueComment ghIssueComment) throws IOException{
        return ghIssueComment.getUser().getLogin();
    }

    private void addParticipantMap(Map<String, Integer> participantMap, String participant) {
        if (participantMap.containsKey(participant)) {
            Integer doHomeworks = participantMap.get(participant);
            participantMap.put(participant, ++doHomeworks);
        } else {
            participantMap.put(participant, 1);
        }
    }

    private void printDashboard(Map<String, Integer> participantMap, int issuesSize) {
        participantMap.forEach((key, value) -> {
            double percent = (double) (value * 100) / issuesSize;
            System.out.print("참여자 : " + key);
            System.out.printf(", 참여율 : %.2f\n", percent);
        });
    }
}


 

IssueReplyUser 코드

 


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

LinkedList

  • LinkedList에서 하나의 Node는 데이터(value)와 다음 노드를 가리키는 포인터(next)를 가집니다.
  • 자신의 다음 노드를 가리키며 연결된 구조입니다.
  • 삽입과 삭제는 Big-O(1) 로 해결할 수 있는 장점이 있습니다.
  • 원하는 위치에 삽입과 삭제를 위해서 원하는 위치나 데이터를 찾기위해 Big-O(n)의 시간이 추가적으로 발생한다는 단점이 있습니다.
  • 결국 삽입, 삭제, 검색에 모두 O(n) 이라는 시간이 걸리지만 LinkedList는 트리구조의 근간이 되는 자료구조입니다.

head : 첫번째 노드를 가리키는 변수로 데이터(value)는 가지지 않습니다. 노드가 없다면 null을 가집니다.

next : 다음 노드를 가리키는 변수로 null값을 가지면 현재의 노드가 마지막 노드임을 의미합니다.

 

public class ListNode {

    ListNode head; // 머리노드
    ListNode next; // 현재 선택 노드
    Integer value; // 값
    private int length = 0;

    ListNode() {
        this.head = this;
    }

    ListNode(int value) {
        this.value = value;
    }

    ListNode add(ListNode head, ListNode nodeToAdd, int position) {
        if (position == 0) {
            if (head.next == null) {
                head.next = nodeToAdd;
                length++;
                return nodeToAdd;
            }
        }

        if (!checkAvailablePosition(position - 1)) {
            System.out.println("Out of ListNode range");
            return null;
        }
        ListNode currentNode = head;

        for (int i = 0; i < position; i++) {
            currentNode = currentNode.next;
        }

        nodeToAdd.next = currentNode.next;
        currentNode.next = nodeToAdd;
        this.length++;
        return nodeToAdd;
    }

    ListNode remove(ListNode head, int positionToRemove) {
        if (!checkAvailablePosition(positionToRemove)) {
            System.out.println("Out of ListNode range");
            return null;
        }

        ListNode currentNode = head;

        for (int i = 0; i < positionToRemove; i++) {
            currentNode = currentNode.next;
        }
        ListNode deleteNode = currentNode.next;
        currentNode.next = currentNode.next.next;
        length--;
        return deleteNode;
    }

    boolean contains(ListNode head, ListNode nodeToCheck) {
        ListNode currentNode = head.next;
        for (int i = 0; i < length(); i++) {
            if (currentNode.value == nodeToCheck.value) {
                return true;
            }
            currentNode = currentNode.next;
        }
        return false;
    }

    private boolean checkAvailablePosition(int position) {
        if (position > length - 1 || position < 0) {
            System.out.println("Out of ListNode range");
            return false;
        }
        return true;
    }

    public int length() {
        return length;
    }

    @Override
    public String toString() {
        ListNode currentNode = head.next;
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < length; i++) {
            sb.append(currentNode.value + ", ");
            currentNode = currentNode.next;
        }
        sb.append("]");
        return sb.toString();
    }
}

 

ListNode 테스트 코드

 

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class ListNodeTest {

    ListNode listNode;

    @BeforeEach
    public void listNode_객체생성() {
        listNode = new ListNode();
        listNode.add(listNode, new ListNode(3), 0);
    }

    @Test
    public void 노드_추가된다() {
        assertEquals(listNode.next.value, 3);
    }

    @Test
    public void 노드_삭제된다() {
        int beforeLengthToRemove = listNode.length();
        ListNode deleteNode = listNode.remove(listNode, 0);
        int afterLengthToRemove = listNode.length();
        assertEquals(deleteNode.value, 3);
        assertEquals(beforeLengthToRemove - 1, afterLengthToRemove);
    }

    @Test
    public void 노드검색() {
        assertTrue(listNode.contains(listNode, new ListNode(3)));
    }


}

 

ListNode 코드

ListNodeTest 코드


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

  • int 배열을 사용해서 정수를 저장하는 Stack을 구현하세요.
  • void push(int data)를 구현하세요.
  • int pop()을 구현하세요.
public class MyStack {
    int[] stack;
    int capacity;
    int pointer;

    public MyStack(int capacity) {
        this.capacity = capacity;
        pointer = 0;
        try {
            stack = new int[capacity];
        }catch (OutOfMemoryError e) {
            capacity = 0;
        }
    }

    public void push(int data) throws OverflowStackException{
        if (pointer >= capacity) {
            throw new OverflowStackException();
        }
        stack[pointer++] = data;
    }

    public int pop() throws EmptyStackException{
        if (pointer <= 0) {
            throw new EmptyStackException();
        }
        return stack[--pointer];
    }
}

class EmptyStackException extends RuntimeException {
}

class OverflowStackException extends RuntimeException {

}

 

Stack 테스트 코드

 

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

public class MyStackTest {

    MyStack stack;

    @BeforeEach
    public void MyStack_객체생성() {
        stack = new MyStack(10);
    }

    @Test
    public void push_작동한다() {
        stack.push(10);
        assertEquals(stack.pointer, 1);
    }

    @Test
    public void pop_작동한다() {
        stack.push(10);
        assertEquals(stack.pop(), 10);
        assertEquals(stack.pointer, 0);
    }

    @Test
    public void OverflowStackException_발생한다() {
        Exception exception = assertThrows(OverflowStackException.class,
                () -> {
                    for (int i = 0; i < 50; i++) {
                        stack.push(i);
                    }
                });
    }

    @Test
    public void EmptyStackException_발생한다() {
        Exception exception = assertThrows(EmptyStackException.class,
                () -> stack.pop());
    }


}

 

MyStack 코드

MyStackTest 코드


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

  • ListNode head를 가지고 있는 ListNodeStack 클래스를 구현하세요.
  • void push(int data)를 구현하세요.
  • int pop()을 구현하세요.
public class ListNodeStack {
    ListNode head;

    public ListNodeStack() {
        this.head = new ListNode();
    }

    public void push(int data) {
        head.add(head, new ListNode(data), head.length());
    }

    public int pop() {
        ListNode removedNode = head.remove(head, head.length() - 1);
        return removedNode.value;
    }

}

 

ListNodeStack 테스트 코드

 

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

public class ListNodeStackTest {

    ListNodeStack listNodeStack;

    @BeforeEach
    public void ListNodeStack_객체생성() {
        listNodeStack = new ListNodeStack();
    }

    @Test
    public void push_된다() {
        listNodeStack.push(10);
        assertEquals(listNodeStack.head.length(), 1);
    }

    @Test
    public void pop_된다() {
        listNodeStack.push(10);
        assertEquals(listNodeStack.pop(), 10);
    }
}

 

ListNodeStack 코드

ListNodeStackTest 코드


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

  • 배열을 사용해서 한번
  • ListNode를 사용해서 한번

배열을 사용한 Queue

public class MyQueue {
    int capacity;
    int front;
    int rear;
    int size;
    int[] queue;

    MyQueue(int capacity) {
        this.capacity = capacity;
        size = 0;
        front = 0;
        rear = 0;
        queue = new int[capacity];
    }

    public void offer(int data) {
        if (size >= capacity) {
            throw new OverflowQueueException();
        }
        queue[rear++] = data;
        size++;

        if (rear == capacity) {
            rear = 0;
        }
    }

    public int poll() {
        if (size <= 0) {
            throw new EmptyQueueException();
        }
        size--;
        int num = queue[front++];

        if (front == capacity) {
            front = 0;
        }

        return num;
    }

}

class EmptyQueueException extends RuntimeException {}

class OverflowQueueException extends RuntimeException {}

 

Queue 테스트코드

 

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

public class MyQueueTest {

    MyQueue queue;

    @BeforeEach
    public void MyQueue_객체생성() {
        queue = new MyQueue(10);
    }

    @Test
    public void offer_된다() {
        queue.offer(10);
        assertEquals(queue.size, 1);
    }

    @Test
    public void poll_된다() {
        queue.offer(10);
        assertEquals(queue.poll(), 10);
    }

    @Test
    public void OverflowQueueException_발생한다() {
        Exception exception = assertThrows(OverflowQueueException.class,
                () -> {
                    for (int i = 0; i < 50; i++) {
                        queue.offer(i);
                    }
                });
    }

    @Test
    public void EmptyQueueException_발생한다() {
        Exception exception = assertThrows(EmptyQueueException.class,
                () -> queue.poll());
    }

}

 

MyQueue 코드

MyQueueTest 코드

 


ListNode를 사용해서 구현한 Queue

public class ListNodeQueue {
    ListNode head;

    ListNodeQueue() {
        this.head = new ListNode();
    }

    public void offer(int data) {
        head.add(head, new ListNode(data), head.length());
    }

    public int poll() {
        ListNode removedNode = head.remove(head, 0);
        return removedNode.value;
    }
}

 

ListNodeQueue 테스트코드

 

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

public class ListNodeQueueTest {
    ListNodeQueue listNodeQueue;

    @BeforeEach
    public void ListNodeQueue_객체생성() {
        listNodeQueue = new ListNodeQueue();
    }

    @Test
    public void offer_된다() {
        listNodeQueue.offer(10);
        assertEquals(listNodeQueue.head.length(), 1);
        assertTrue(listNodeQueue.head.contains(listNodeQueue.head, new ListNode(10)));
    }

    @Test
    public void poll_된다() {
        listNodeQueue.offer(10);
        int num = listNodeQueue.poll();
        assertEquals(num, 10);
        assertTrue(listNodeQueue.head.length() == 0);
    }

}

 

ListNodeQueue 코드

ListNodeQueueTest 코드


 

참고

- pureainu.tistory.com/190

- junit.org/junit5/docs/current/user-guide/

 

'java-liveStudy' 카테고리의 다른 글

6주차 과제. 상속  (0) 2020.12.25
5주차. 과제  (0) 2020.12.17
5주차. 클래스  (0) 2020.12.16
3주차 과제. 연산자  (0) 2020.11.26
2주차 과제. 자바의 프리미티브 타입, 변수 그리고 배열  (0) 2020.11.21

댓글