4주차 과제: 제어문

2020. 12. 12. 03:32백기선의 온라인 자바 스터디

반응형

- 목표

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


- 학습할 것

  • 선택문
  • 반복문

과제 (옵션)

과제 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()을 구현하세요.

과제 5. Queue를 구현하세요.

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

● 선택문

  • 조건문 : if문, switch문

 if 문 

- 가장 기본적인 조건문, '만일(if) 조건식이 참(true)이면 괄호{} 안의 문장들을 수행하라'라는 의미로 이해.

if (조건식) {
	//조건식이 참(true)일 때 수행될 문장들을 적는다.
}

 

 If-else 문 

- 조건식의 결과가 참이 아닐 때, 즉 거짓일 때 else블럭의 문장을 수행하라는 의미.

if (조건식) {
	// 조건식이 참(true)일 때 수행될 문장들을 적는다.
} else {
	// 조건식이 거짓(false)일 때 수행될 문장들을 적는다.
}

//단 if-else문 블럭 내의 문장이 한줄일 경우 괄호{}를 생략할 수 있다.

 

 if-else if 문 

- 처리해야 할 경우의 수가 셋 이상인 경우에 사용된다. 만일 결과가 참인 조건식이 하나도 없으면, 마지막에 있는 else블럭의 문장들이 수행되고 이 else블럭은 생략이 가능하다.

if (조건식1) {
	// 조건식1의 연산결과가 참일 때 수행될 문장들을 적는다.
    
} else if (조건식2) {
	// 조건식2의 연산결과가 참일 때 수행될 문장들을 적는다.
    
} else if (조건식3) {   //여러개의 else if를 사용할 수 있다.
	// 조건식3의 연산결과가 참일 때 수행될 문장들을 적는다.
    
} else {   //마지막에는 보통 else블럭으로 끝나며, else블럭은 생략 가능하다.
	// 위의 어느 조건식도 만족하지 않을 때 수행될 문장들을 적는다.
    
}

 

 중첩 if문 

- if문 블럭 내에 또 다른 if문을 포함시키는 것. 중첩의 횟수는 거의 제한이 없다.

if (조건식1) {
	//조건식1의 연산결과가 true일 때 수행될 문장들을 적는다.
    
    if (조건식2) {
    	//조건식1과 조건식2가 모두 true일 때 수행될 문장들
    } else {
    	// 조건식1이 true이고, 조건식2가 false일 때 수행되는 문장들
    }
    
} else {
	//조건식1이 false일 때 수행되는 문장들
}

 

 switch 문 

- 단 하나의 조건식으로 많은 경우의 수를 처리할 수 있는 방식. 다만, switch문은 제약조건이 있기 때문에, 경우의 수 가 많아도 어쩔 수 없이 if문으로 작성해야 하는 경우가 있다.

  1. 조건식을 계산한다.
  2. 조건식의 결과와 일치하는 case문으로 이동한다.
  3. 이후의 문장들을 수행한다.
  4. break문이나 swtich문의 끝을 만나면 switch문 전체를 빠져나간다.
switch (조건식) {
	case 값1 :
    	// 조건식의 결과가 값1과 같을 경우 수행될 문장들
        //....
        break;
    case 값2 :
    	// 조건식의 결과가 값2와 같을 경우 수행될 문장들
        //....
        break;
    //....
    default :
    	// 조건식의 결과와 일치하는 case문이 없을 때 수행될 문장들
        //.... esle의 용도와 비슷하다.
}

- switch문도 if문 처럼 중첩이 가능하다. 한 가지 주의할 점은 switch문에서 break문을 빼먹기 쉽다. 조심하자.

 switch문의 제약조건 

  1. switch문의 조건식 결과는 정수 또는 문자열이어야 한다.
  2. case문의 값은 정수 상수만 가능하며, 중복되지 않아야 한다.

 

● 반복문

  • 반복문 : for문, while문, do-while문
  • 분기문 : break, continue, return

 for문

- 반복 횟수를 알고있을 때 적합한 방법. 

- for문은 '초기화', '조건식', '증감식', '블럭{}', 모두 4부분으로 이루어져 있으며, 조건식이 참인 동안 블럭내의 문장들을 반복하다 거짓이 되면 반복문을 벗어난다.

for (초기화; 조건식; 증감식) {
	// 조건식이 참일 때 수행될 문장들을 적는다.
}

 

      - 초기화 : 반복문에 사용될 변수를 초기화하는 부분이며 처음에 한번만 수행된다. 보통 변수 하나로 for문을 제어.
    - 조건식 : 조건식의 값이 참(true)이면 반복을 계속하고, 거짓(false)이면 반복을 중단하고 for문을 벗어난다. 조건식이 '참인동안' 반복을 계속 한다. 단, 조건식을 잘못 작성하면 실행되지 않거나 무한루프로 가기 쉬우므로 주의.
    - 증감식 : 반복문을 제어하는 변수의 값을 증가 또는 감소 시키는 식이다. 매 반복마다 변수의 값이 증감식에 의해서 점진적으로 변하다가 결국 조건식이 거짓이 되어 for문을 벗어나게 된다. 변수의 값을 1씩 증가시키는 연산자 '++'이 증감식에 주로 사용된다.
    - for문도 if문처럼 for문안에 for문을 포함시키는 중첩이 가능하다. 중첩의 횟수는 거의 제한이 없다.

 

 향상된 for문

for ( 타입 변수명 : 배열 또는 컬렉션 ) {
	// 반복할 문장
}

위의 문장에서 타입은 배열 또는 컬렉션의 요소의 타입이어야 한다. 배열 또는 컬렉션에 저장된 값이 매 반복마다 하나씩 순서대로 읽혀서 변수에 저장된다.(배열 또는 컬렉션의 모든 값을 돌리고 싶을때) 그리고 반복문의 괄호{} 내에서는 이 변수를 사용해서 코드를 작성한다.

 

while문

- 조건식이 '참(true)인 동안', 즉 조건식이 거짓이 될 때까지 블럭{} 내의 문장을 반복한다.

while (조건식) {
	// 조건식의 연산결과가 참(true)인 동안, 반복될 문장들을 적는다.
}
  1. 조건식이 참(true)이면 블럭{}안으로 들어가고, 거짓(false)이면 while문을 벗어난다.
  2. 블럭{}의 문장을 수행하고 다시 조건식으로 돌아간다.

- for문과 while문은 크게 다르지 않다. 만일 초기화나 증감식이 필요하지 않은 경우라면, while문이 더 적합할 수도 있다.

- while(조건식) --> 조건식이 없을 경우에는 에러가 발생한다.

 

 do-while문 

- while문의 조건식과 블럭{}의 순서를 바꿔놓은 것이다. 그래서 while문과 반대로 블럭{}을 먼저 수행한 후에 조건식을 평가한다. while문은 조건식의 결과에 따라 블럭{}이 한 번도 수행되지 않을 수 있지만, do-while문은 최소한 한번은 수행될 것을 보장한다.

do {
	// 조건식의 연산결과가 참일 때 수행될 문장들을 적는다.
} while (조건식);  //<--- 끝에 ';'을 잊지 않도록 주의.

 

 break문 

- 반복문에서도 break문을 사용할 수 있는데, break문은 자신이 포함된 가장 가까운 반복문을 벗어난다. 주로 if문과 함께 사용되어 특정 조건을 만족하면 반복문을 벗어나도록 한다.

class Testbreak {
	public static void main(String[] args){
    	int sum = 0;
        int i   = 0;
        
        while (true) {
        	if(sum > 100)
            	break;
            ++i;
            sum += i;
        } //end of while
        
        System.out.println("i=" +i);   // i=14
        System.out.println("sum=" + sum);    // sum=105
    }
}

break문이 수행되면 이 부분은 실행되지 않고 while문을 완전히 벗어난다.

 continue문 

- 반복문 내에서만 사용될 수 있으며, 반복이 진행되는 도중에 continue문을 만나면 반복문의 끝으로 이동하여 다음 반복으로 넘어간다. break와 달리 반복문을 벗어나지는 않고 다음 반복을 계속 수행한다.

class Testcontinue {
	public static void main (String[] args) {
    	for(int i=0; i<=10; i++) {
        	if(i%3==0)
            	continue;   //조건식이 참이 되어 continue문이 수행되면 블럭의 끝으로 이동한다.
            System.out.print(i+ " ");
        }
    }
}

실행결과 : 1 2 3 4 5 6 7 8 10

 

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

 JUnit 이란?

- JUnit은 Java를 위한 단위 테스트 (Unit Test) 프레임워크로 개발하는 프로그램에 대한 테스트케이스를 쉽게 작성할 수 있도록 도와줍니다.

- JUnit4 에서 JUnit5로 넘어오면서 달라진 점은 Java8이상의 개발환경에서 수행할 수 있다.

- JUnit5 구조

출처 사진보기.

JUnit5 =  JUnit Platform + JUnit  Jupiter  + Junit Vintage

  • JUnit  Platform : 테스트를 발견하고 테스트 계획을 생성하는 TestEngine 인터페이스를 가지고 있습니다. Platform은 TestEngine을 통해서 테스트를 발경하고 ,실행하고 ,결과를 보고합니다.
  • JUnit Jupiter : TestEngine의 실제 구현체는 별도 모듈입니다. 모듈 중 하나가 jupiter-engine입니다. 이 모듈은 jupiter-api를 사용해서 작성한 테스트 코드를 발견하고 실행합니다. Jupiter API는 JUnit 5에 새롭게 추가된 테스트 코드용 API로서, 개발자는 Jupiter API를 사용해서 테스트 코드를 작성할 수 있습니다
  • JUnit Vintage : 기존에 JUnit 4 버전으로 작성한 테스트 코드를 실행할 때에는 vintage-engine 모듈을 사용합니다.
                         (JUnit5 상에서 JUnit3,JUnit4 기반의 테스트들이 구동되는것을 지원.)

- JUnit 설정

필자는 Maven Project로 예시를 보여드릴 예정이다. (테스트 코드는 밑에 stack, LinkedList,queue에서 보여드릴 예정.)

- eclipse에서 Maven project를 선택을 한 후 Artifact를 설정 해준다.

Artifact 설정

여기서 보시는 Group id는 모든 프로젝트 중에서 내 프로젝트를 식별해주는 식별자, 즉 내가 백화점상품 관련 프로젝트를 수행 한다면 해당 백화점 이름이 되는것이며, Artifact id는 이 백화점 프로젝트의 각 기능들이라 생각하면 된다. 예를들어 의류/음식/스포츠용품... 이런 것들로 볼 수 있다. 이들은 추 후에 dependencies추가 할때 볼 수 있을 것이다.

- pom.xml 파일에서 Maven dependency 설정을 해주어야 한다. (이부분은 개인마다 조금 다른거 같아 많이 찾아보고 이해할 필요성이 있는거 같다.)

의존성 주입. 빨간표시의 오류는 신경 x

- 위 보시는 바와 같이 properties에 jupiter.version을 따로 설정해주고 dependency의 jupiter-api와 jupiter-engine에 &{}를 사용하여 주입해줘도 된다. 이방법을 사용하지 않고 api와 engine버전을 따로 사용하고 싶다면,,, 

mvnrepository.com 이곳에서 junit을 검색한 후에 dependency Maven을 복사해서 pom.xml에 붙여넣기 해도 무방하다. 그러나 필자는 api와 engine의 똑같은 버전을 사용할 것을 추천한다. 설정은 가볍게 마무리 하겠다.

- JUnit5의 테스트 프레임을 돕기위한 어노테이션(Annotation).

Annotation

description

@Test

방법은 테스트 방법임을 나타냅니다. JUnit 4의 @Test주석 과 달리이 주석은 속성을 선언하지 않습니다. JUnit Jupiter의 테스트 확장 프로그램은 자체 전용 주석을 기반으로 작동하기 때문입니다. 이러한 메서드는 재정의 되지 않는 한 상속 됩니다 .

@ParameterizedTest

메소드는 매개 변수화 된 테스트 임을 나타냅니다 . 이러한 메서드는 재정의 되지 않는 한 상속 됩니다 .

@RepeatedTest

방법은 반복 테스트를 위한 테스트 템플릿임을 나타냅니다 . 이러한 메서드는 재정의 되지 않는 한 상속 됩니다 .

@TestFactory

방법은 동적 테스트를 위한 테스트 팩토리임을 나타냅니다 . 이러한 메서드는 재정의 되지 않는 한 상속 됩니다 .

@TestTemplate

메소드는 등록 된 제공자가 리턴 한 호출 컨텍스트의 수에 따라 여러 번 호출되도록 설계된 테스트 케이스 의 템플리트 임을 나타냅니다 . 이러한 메서드는 재정의 되지 않는 한 상속 됩니다 .

@TestMethodOrder

어노테이션이있는 테스트 클래스에 대한 테스트 메소드 실행 순서 를 구성하는 데 사용됩니다 . JUnit 4와 유사합니다 @FixMethodOrder. 이러한 주석은 상속 됩니다.

@TestInstance

어노테이션이있는 테스트 클래스에 대한 테스트 인스턴스 라이프 사이클 을 구성하는 데 사용됩니다 . 이러한 주석은 상속 됩니다.

@DisplayName

테스트 클래스 또는 테스트 메소드 의 사용자 정의 표시 이름 을 선언합니다 . 이러한 주석은 상속 되지 않습니다 .

@DisplayNameGeneration

테스트 클래스에 대한 사용자 정의 표시 이름 생성기 를 선언합니다 . 이러한 주석은 상속 됩니다.

@BeforeEach

주석 메소드가 실행되어야 나타낸다고 전에 각각 @Test , @RepeatedTest, @ParameterizedTest, 또는 @TestFactory현재의 메소드; JUnit 4와 유사합니다 @Before. 이러한 메서드는 재정의 되지 않는 한 상속 됩니다 .

@AfterEach

주석 메소드가 실행되어야 나타낸다고 후에 각각 @Test , @RepeatedTest, @ParameterizedTest, 또는 @TestFactory현재의 메소드; JUnit 4와 유사합니다 @After. 이러한 메서드는 재정의 되지 않는 한 상속 됩니다 .

@BeforeAll

주석 메소드가 실행되어야 함을 나타내고 전에 모든 @Test , @RepeatedTest, @ParameterizedTest및 @TestFactory현재 클래스의 메소드; JUnit 4와 유사합니다 @BeforeClass. 이러한 메소드는 ( 숨겨 지거나 재정의 되지 않는 한) 상속 되며 "클래스 별" 테스트 인스턴스 라이프 사이클 이 사용 되지 않는 한 있어야합니다 .static

@AfterAll

주석 메소드가 실행되어야 함을 나타내고, 이후 모든 @Test , @RepeatedTest, @ParameterizedTest및 @TestFactory현재 클래스의 메소드; JUnit 4와 유사합니다 @AfterClass. 이러한 메소드는 ( 숨겨 지거나 재정의 되지 않는 한) 상속 되며 "클래스 별" 테스트 인스턴스 라이프 사이클 이 사용 되지 않는 한 있어야합니다 .static

@Nested

주석이 달린 클래스는 정적이 아닌 중첩 테스트 클래스 임을 나타냅니다 . @BeforeAll및 @AfterAll방법은 직접 사용할 수 없습니다 @Nested은 "당 클래스"를 제외 테스트 클래스 테스트 인스턴스 라이프 사이클이 사용됩니다. 이러한 주석은 상속 되지 않습니다 .

@Tag

클래스 또는 메소드 레벨에서 필터링 테스트를위한 태그 를 선언하는 데 사용됩니다 . TestNG의 테스트 그룹 또는 JUnit 4의 카테고리와 유사합니다. 이러한 주석은 클래스 레벨에서 상속 되지만 메소드 레벨 에서는 상속 되지 않습니다.

@Disabled

테스트 클래스 또는 테스트 방법 을 비활성화 하는 데 사용됩니다 . JUnit 4와 유사합니다 @Ignore. 이러한 주석은 상속 되지 않습니다 .

@Timeout

실행이 주어진 기간을 초과하는 경우 테스트, 테스트 팩토리, 테스트 템플릿 또는 수명주기 방법에 실패합니다. 이러한 주석은 상속 됩니다.

@ExtendWith

확장을 선언적 으로 등록하는 데 사용됩니다 . 이러한 주석은 상속 됩니다.

@RegisterExtension

필드를 통해 프로그래밍 방식으로 확장 을 등록하는 데 사용됩니다 . 이러한 필드는 음영 처리 되지 않는 한 상속 됩니다 .

@TempDir

수명주기 방법 또는 테스트 방법에서 필드 주입 또는 매개 변수 주입을 통해 임시 디렉토리 를 제공하는 데 사용됩니다 . 에있는 org.junit.jupiter.api.io패키지.

JUnit Test 는 밑에 과제 3-4-5의 과정으로 보여드릴것이다.

 

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

 

 

(4주차 자료구조 과제 >>GitHub Home URL<<)

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

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

(여기선 LinkedList에 대하여 간략히 설명하고 자세한 내용은 tap- Java에서 확인하실 수 있습니다.)

LinkedList는 배열의 단점을 보완하기 위해서 나온 자료구조이다.(ArrayList는 배열을 응용해서 나온 자료구조) 배열의 단점은 크기를 변경할 수 없으며 비순차적인 데이터의 추가 또는 삭제에 시간이 많이 걸린다는 것을 볼 수 있다. 이에 대하여 링크드리스트는 불연속적으로 존재하는 데이터(Node)를 서로 연결(link)한 형태로 구성되어 있다.

LinkedList 코드

LinkedList 테스트 코드

 

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

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

Stack 코드

Stack 테스트 코드

 

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

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

ListNode Stack 코드

ListNode Stack 테스트 코드

 

과제 5. Queue를 구현하세요.

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

ArrayQueue 코드

ArrayQueue 테스트 코드

ListNode Queue 코드

ListNode Queue 테스트 코드

반응형