[Java] 4주차 과제: 제어문
by Roel Downey
스터디 링크 : 링크
프로그램이 원하는 결과를 얻기 위해서는 프로그램의 순차적인 흐름을 제어해야만 할 경우가 생긴다. 이때 사용하는 명령문을 제어문이라고 하며, 이러한 제어문에는 선택문(조건문), 반복문 등이 있다.
이러한 제어문에 속하는 명령문들은 중괄호 { } 로 둘러 싸여있으며, 이러한 중괄호 영역을 블록이라고 한다.
선택문
선택문은 주어진 조건의 결과에 따라 별도의 명령을 수행하도록 제어하는 명령문이다.선택문 중에서도 가장 기본이 되는 명령문은 if 문이다.
자바에서 사용하는 대표적인 조건문의 형태는 다음과 같다.1. if문2. if / else 문3. if / else if / else 문4. switch 문
if 문
if 문은 조건식의 결과가 참(true)이면 주어진 명령문을 실행하며, 거짓이면 아무것도 실행하지 않는다.
자바에서 if 문의 문법은 아래와 같다.
문법 if (조건식) { 조건식의 결과가 참일 때 실행하고자 하는 명령문; } |
위의 코드에서 블록에 속한 명령문은 중괄호를 기준으로 오른쪽으로 들여쓰기가 되어 있는 것을 볼 수 있다.
이처럼 들여쓰기를 통해 코드의 가독성을 높이는 것을 인덴트(indent)라고 하며, 될 수 있으면 모든 코드를 인덴트하는 것이 좋다.
if (ch >= 'a' && ch <= 'z') {
System.out.println("해당 문자는 영문 소문자 이다. ")
}
위의 예제는 if 문을 사용하여, 해당 문자가 영문 소문자인지를 확인하는 예제이다.
- if 문에서 실행될 명령문이 한 줄 뿐이라면 중괄호를 생략할 수 있다.
if / else 문
if 문과 함께 else 문은 if 문과는 반대로 주어진 조건식의 결과가 거짓(false)이면 주어진 명령문을 실행한다.
자바에서 if / else 문의 문법은 아래와 같다.
문법 if (조건식) { 조건식의 결과가 참일 때 실행하고자 하는 명령문; } else { 조건식의 결과가 거짓일 때 실행하고자 하는 명령문; } |
if (ch >= 'a' && ch <= 'z') {
System.out.println("해당 문자는 영문 소문자 이다. ")
} else {
System.out.println("해당 문자는 영문 소문자가 아니다.")
}
위의 예제는 if / else 문을 사용하여, 해당 문자가 영문 소문자인지를 확인하는 예제이다.
if / else if / else 문
if / else if / else 문은 마치 새로운 구문처럼 보이지만, 사실은 두개의 if / else 문이 연달아 나온것이다.
자바에서 if / else if /else 문의 문법은 아래와 같다.
문법 if (조건식1 ) { 조건식1 의 결과가 참일 때 실행하고자 하는 명령문; } else if (조건식2) { 조건식2 의 결과가 참일 때 실행하고자 하는 명령문; } else { 조건식1,2의 결과가 거짓일 때 실행하고자 하는 명령문; } |
else if 문을 여러 번 나와도 상관 없지만, if문과 else 문은 단 한 번만 나올 수 있다.
if (ch >= 'a' && ch <= 'z') {
System.out.println("해당 문자는 영문 소문자입니다.");
} else if (ch >= 'A' && ch <= 'Z') {
System.out.println("해당 문자는 영문 대문자입니다.");
} else {
System.out.println("해당 문자는 영문자가 아닙니다.");
}
위의 예제는 if / else if / else 문을 사용하여, 해당 문자가 영문 소문자인지, 영문 대문자인지, 아니면 영문자가 아닌지를 확인하는 예제이다.
삼항 연산자에 의한 조건문
자바에서는 간단한 if / else 문은 삼항 연산자를 이용하여 간결하게 표현할 수 있다.
문법 조건식 ? 반환값1 : 반환값2 |
물음표(?) 앞의 조건식에 따라 결과값이 참이면 반환값1 을 반환하고, 결과값이 거짓이면 반환값2를 반환한다.
int number1 = 5, number2 = 10;
int result = 0;
result = (number1 - number2 > 0 ) ? number1 : number2;
System.out.println("두 정수 중 더 큰 수는 " + result + "이다.");
위의 예제는 삼항연산자를 사용하여, 두 정수 중 더 큰 수를 찾는 예제이다.
switch 문
switch 문은 if / else 문과 마찬가지로 주어진 조건 값의 결과에 따라 프로그램이 다른 명령을 수행하도록 하는 조건문이다.
이러한 switch 문을 if / else 문보다 가독성이 더 좋으며, 컴파일러가 최적화를 쉽게 할 수 있어 속도 또한 빠른 편이다.
하지만 switch 문의 조건 값으로는 int형으로 승격할 수 있는 (integer promotion) 값만이 사용될 수 있다.
즉, switch 문의 조건 값으로 byte , short , char , int 변수나 리터럴을 사용 할 수 있다.
또한, 이러한 기본 타입에 해당하는 데이터를 객체로 포장해 주는 래퍼 클래스 중에서 위에 해당하는 클래스 객체도 사용할 수 있다.
그리고 enum 키워드를 사용한 열거체와 String 클래스의 객체도 사용할 수 있다.
따라서 switch 문은 if / else 문보다는 사용할 수 있는 상황이 적다.
자바에서 switch 문의 문법은 아래와 같다.
문법 switch (조건 값) { case 값1: 조건 값이 값1일 때 실행하고자 하는 명령문; break; case 값2: 조건 값이 값2일 때 실행하고자 하는 명령문; break; .... default: 조건 값이 어떠한 case 절에도 해당하지 않을 때 실행하고자 하는 명령문; break; } |
switch (ch) {
case 'a':
System.out.println("해당 문자는 'A'입니다.");
break;
case 'e':
System.out.println("해당 문자는 'E'입니다.");
break;
case 'i':
System.out.println("해당 문자는 'I'입니다.");
break;
case 'o':
System.out.println("해당 문자는 'O'입니다.");
break;
case 'u':
System.out.println("해당 문자는 'U'입니다.");
break;
default:
System.out.println("해당 문자는 모음이 아닙니다.");
break;
}
위의 예제는 switch문을 사용하여, 해당 문자가 영문자 모음인지를 확인하는 예제이다.
case절 및 default 절은 반드시 break 키워드를 포함하고 있어야 한다.
break 키워드는 조건 값에 해당하는 case 절이나 dafault 절이 실행된 뒤에 전체 switch 문을 빠져나가게 해준다.
만약 break 키워드가 없다면, 조건에 해당하는 switch 문의 case 절 이후의 모든 case 절이 전부 실행 될 것이다.
다음 예제는 앞서 살펴본 예제에서 break 키워드를 모두 삭제한 예제이다.
switch (ch) {
case 'a':
System.out.println("해당 문자는 'A'입니다.");
case 'e':
System.out.println("해당 문자는 'E'입니다.");
case 'i':
System.out.println("해당 문자는 'I'입니다.");
case 'o':
System.out.println("해당 문자는 'O'입니다.");
case 'u':
System.out.println("해당 문자는 'U'입니다.");
default:
System.out.println("해당 문자는 모음이 아닙니다.");
}
위의 예제처럼 break 키워드가 없으면, 조건 값에 해당하는 case 절 뿐만 아니라 그 이후에 등장하는 모든 case 절과 default 절이 전부 실행된다.
반복문
반복문이란? 프로그램 내에서 똑같은 명령을 일정 횟수만큼 반복하여 수행하도록 제어하는 명령문 이다.
프로그램이 처리하는 대부분의 코드는 반복적인 형태가 많으므로, 가장 많이 사용되는 제어문 중 하나이다.
자바에서 사용되는 대표적인 반복문의 형태는 다음과 같다.
1. while 문
2. do / while 문
3. for 문
4. Enhanced for 문
while 문
while 문은 특정 조건을 만족 할 때 까지 계속해서 주어진 명령문을 반복 실행 합니다.
자바에서 while 문의 문법은 다음과 같다.
문법 while(조건식) { 조건식의 결과가 참인 동안 반복적으로 실행하고자 하는 명령문; } |
while 문은 우선 조건식이 참인지 판단하여, 참이면 내부의 명령문을 실행한다.
내부의 명령문을 전부 실행하고 나면, 다시 조건식으로 돌아와 또 한번 참인지를 판단하게 된다.
이렇게 조건식의 검사를 통해 반복해서 실행되는 반복문을 루프(loop)라고 한다.
int i = 0;
while (i < 5) {
i++; // 이 부분을 삭제하면 무한 루프에 빠지게 됨.
System.out.println("while 문이 " + (i) + "번째 반복 실행중입니다.");
}
System.out.println("while 문이 종료된 후 변수 i의 값은 " + i + "입니다.");
위의 예제는 while 문을 5번 반복해서 실행하는 예제이다.
while 문 내부에 조건식의 결과를 변경하는 명령문이 존재하지 않을 때는 프로그램이 영원히 반복되게 된다.
이것을 무한 루프(infinite loop)에 빠졌다고 하며, 무한 루프에 빠진 프로그램은 영원히 종료되지 않는다.
무한 루프는 특별히 의도한 경우가 아니라면 반드시 피해야 하는 상황이다.
따라서 while 문을 작성할 때는 조건식의 결과가 어느 순간 거짓(false)을 갖도록 조건식의 결과를 변경하는 명령문을 반드시 포함 시켜야한다.
do while 문
do while 문은 루프에 진입하기 전에 먼저 조건식 부터 검사한다.
하지만 do / while 문은 먼저 루프를 한 번 실행한 후에 조건식을 검사한다.
즉 do / while 문은 조건식의 결과와 상관없이 무조건 한 번은 루프를 실행한다.
문법 do { 조건식의 결과가 참인 동안 반복적으로 실행하고자 하는 명령문; }while(조건식); |
int i = 1, j = 1;
while (i < 1) {
System.out.println("while 문이 " + i + "번째 반복 실행중입니다.");
i++; // 이 부분을 삭제하면 무한 루프에 빠지게 됨.
}
System.out.println("while 문이 종료된 후 변수 i의 값은 " + i + "입니다.");
do {
System.out.println("do / while 문이 " + i + "번째 반복 실행중입니다.");
j++; // 이 부분을 삭제하면 무한 루프에 빠지게 됨.
} while (j < 1);
System.out.println("do / while 문이 종료된 후 변수 j의 값은 " + j + "입니다.");
위 예제가 만약 while문이였다면 단 한번의 출력도 없었을 것이다.
하지만 do / while 문은 조건식의 결과와 상관없이 무조건 한 번은 루프를 실행해 준다.
for 문
for 문은 while문과는 달리 자체적으로 초기식, 조건식, 증감식을 모두 포함하고 있는 반복문이다.
따라서 while문보다는 좀 더 간결하게 반복문을 표현할 수 있다.
문법 for (초기식; 조건식; 증감식) { 조건식의 결과가 참인 동안 반복적으로 실행하고자 하는 명령문; } |
int i = 0;
for (i = 0; i < 5; i++) {
System.out.println("for 문이 " + (i + 1) + "번째 반복 실행중입니다.");
}
System.out.println("for 문이 종료된 후 변수 i의 값은 " + i + "입니다.");
Enhanced for 문
Enhanced for 문은 JDK 1.5부터 Enhanced for 문이라는 반복문이 추가 되었다.
이 반복문은 컬렉션 프레임워크와 배열에서 유용하게 자주 사용된다.
문법 for ( 타입 변수이름 : 배열이나 컬렉션 이름) { 배열의 길이만큼 반복적으로 실행하고자 하는 명령문; } |
Enhanced for 문은 명시한 배열이나 컬렉션의 길이만큼 반복되어 실행된다.
루프마다 각 요소는 명시한 변수의 이름으로 저장되며, 명령문에서는 이 변수를 사용하여 각 요소를 참조할 수 있다.
int[] arr = new int[]{1, 2, 3, 4, 5};
for (int e : arr) {
System.out.print(e + " ");
}
하지만 Enhanced for 문은 요소를 참조할 때만 사용하는 것이 좋으며, 요소의 값을 변경하는 작업에는 적합하지 않다.
JUnit5 학습하세요.
JUnit은 자바 프로그래밍 언어용 유닛 테스트 프레임 워크이다.
- 링크 : [ 위키 백과 ]
JUnit은 Java 시스템에서 가장 인기있는 단위테스트 프레임 워크 중 하나이다.
Junit5 버전을 작동하려면 Java 8이 필요하다.
- Annotation
@BeforeAll : 전체 테스트 실행하기 전에 한번만 실행. @Testlnstance 사용하지 않을 경우엔 static 일것.
@Test : 테스트
@AfterAll : 전체 테스트 후에 한번만 실행. @TestInstance 사용하지 않을 경우엔 static 일것
@BeforeEach : 모든 테스트 전에 한번씩 실행
@AfterEach : 모든 테스트 후에 한번씩 실행
@Disabled : 이 테스트 실행하지 않음
@DisplayName("테스트 이름 직접 지정하기") : 어떤 테스트인지 테스트 이름을 보다 쉽게 표현할 수 있는 방법을 제공
@DisplayNameGeneration() : 테스트 클래스에 써도 되고, 테스트 메서드에 써도 된다. Test Results에 테스트 이름을 어떻게 보이게 할지 정함
JUnit 5: Assertion
- assert *
- assertEquals(expected,actual)(실제 값이 기대한 값과 같은지 확인),
- assertNotNull(actual)(값이 null이 아닌지 확인),
- assertTrue(boolean)(다음 조건이 참인지 확인),
- assertTimeout(duration, executable)(특정 시간 안에 실행이 완료 되는지 확인),
- assertThrow(expectedType, executable)(예외 발생 확인)
- assertAll(executables...) 내부의 모든 assert의 결과 보여줌 (한 assert 실패시 다음 assert로 넘어가지 않음)
- assume : 특정 조건에서만 테스트
- assumeTrue(조건)
- assumeFalse(조건)
- assumingThat(조건, 테스트)
- annotation : 특정 조건에서만 테스트하기
- @Enabled
- @Disabled
- annotation : 테스트 태깅하기 ( 테스트 그룹을 만들고 원하는 테스트 그룹만 테스트를 실행할 수 있는 기능 )
- @Tag : 테스트 메소드에 태그를 추가 , 하나의 테스트 메소드에 여러 태그를 사용할 수 있다.
테스트 반복하기
- annotation
- @RepeatedTest : @RepeatedTest(100) 100번 반복하기
- @RepeatedTest + 파라미터 RepetitionInfo
- @RepeatedTest 와 @DisplayName 같이 쓰기
파라미터를 이용해 테스트 반복하기
- annotation
- @parameterizedTest
- @valueSource
- @ParameteriaedTest 와 @DisplayName 같이 쓰기
- @EmptySource : 빈 값 하나를 추가
- @NullSource : null 값 하나를 추가
- @NullAndEmptySource : @NullSource + @EmptySource
파라미터를 이용해 반복해서 한개의 인자를 받는 생성자 객체 생성하기
- annotation
- @ParameterizedTest
- @ValueSource
- @ConvertWith : SimpleArgumentConverter를 상속하여 컨버터 생성해야 함
JUnit5 테스트 순서
테스트 메소드를 원하는 순서에 따라 실행하도록 @TestInstance(Lifecycle.PER_CLASS)와 함께 @TestMethodOrder 를 사용할 수 있다.
- MethodOrderer 구현체를 설정한다.
- 기본 구현체 : Alphanumeic, OrderAnnoation, Random
JUnit5 : junit-platform.propertie : JUnit 설정 파일로, 클래스 패스 루트에 넣어두면 적용된다. (src/test/resources/)
- 테스트 인스턴스 라이프 사이클 설정 : junit.jupiter.testinstance.lifecycle.default = per_class
- 확장팩 자동 감지 기능 : junit.jupiter.extensions.autodetection.enabled = true
- @Disabled 무시하고 실행하기 : junit.jupiter.conditions.deactivate = org.junit.*DisabledCondition
- 테스트 이름 표기 전략 설정 : junit.jupiter.displayname.generator.default = \
org.junit.jupiter.api.DisplayNameGenerator$ReplaceUnderscores
live-study 대시 보드를 만드는 코드를 작성하세요.
LinkedList를 구현하세요.
Stack을 구현하세요.
ListNode를 사용해서 Stack을 구현하세요.
Queue를 구현하세요.
이번과제는 못한 부분도 있어서 많이 아쉽다. 특히 github API 를 활용하는건 나에게 큰 도전이였다. 계속 고민해보고 잘 만들어서 추가해야겠다.
'Java' 카테고리의 다른 글
[Java] Binary Tree (0) | 2020.12.16 |
---|---|
[Java] 5주차 과제: 클래스 (0) | 2020.12.14 |
[Java] 3주차 과제: 연산자 (0) | 2020.11.25 |
[Java] 동시성(Concurrency)과 병렬성(Parallelism) 차이 (0) | 2020.11.17 |
[Java] 2주차 과제: 자바 데이터 타입, 변수 그리고 배열 (0) | 2020.11.16 |
블로그의 정보
What doing?
Roel Downey