2022. 4. 15. 15:02ㆍJava/java-live-study
목표
자바가 제공하는 제어문(Control Statement)을 학습하세요
학습할 것
- 선택문
- 반복문
과제
- JUnit 5를 학습하세요
- live-study 대시 보드를 만드는 코드를 작성하세요
- LinkedList를 구현하세요
- Stack을 구현하세요
- 앞서 만든 ListNode를 사용해서 Stack을 구현하세요
- Queue를 구현하세요
선택문(Decision-making Statement)
if
가장 기본적인 선택문(조건문)으로 소괄호 안의 조건식이 참이면 중괄호 안의 구문을 실행한다.
//if문의 기본적인 형태
if (조건식) {
//구문
}
//if-else 형태
if (조건식1) {
//조건식1이 참이면 실행
}
else if(조건식2) {
//조건식1이 거짓이고 조건식2가 참이면 실행
}
else {
//조건식1, 2 모두 거짓이면 실행
}
자바에서는 조건식에 무조건 boolean 값이 들어가야한다. (0, 1과 같은 숫자 불가)
switch
다중 if문 대신 사용할 수 있는 문법으로 소괄호 안의 조건식과 같은 값의 case 문부터 실행된다. (break 문을 적절히 사용해야함)
- 정수 값이나 열거된 값 또는 문자, 문자열만을 사용할 수 있다.
public class ControlStatementTest {
public static void main(String[] args) {
int num = 1;
switch (num) {
case 1:
System.out.println(1);
case 2:
System.out.println(2);
case 3:
System.out.println(3);
break; //break 문을 만나 1 2 3까지 출력
case 4:
System.out.println(4);
default:
System.out.println("default");
}
}
}
반복문(Looping Statment)
조건식이 참이면 구문 안의 명령을 반복하여 수행한다. for, for-each, while, do-while 문이 있다.
for
for (초기값; 조건; 방향&간격) {
//statement
}
for-each
for (<type> <instance>: <type-iterable>) {
//statement
}
while
while (expression) {
//statement
}
do-while
do {
//statement
} while (expression)
과제 0. JUnit 5를 학습하세요
- 인틸리제이, 이클립스, VS Code에서 JUnit 5로 테스트 코드 작성하느 방법에 익숙해 질 것.
- 더 자바, 테스트 강의 참고
JUnit 5 는 자바 개발자가 가장 많이 사용하는 테스팅 프레임워크이다. JAVA 버전 8 이상을 필요로한다.
JUnit 5 구성(세부 모듈)

JUnit Platform
테스트를 실행해주는 런처를 제공한다. TestEngine API 제공.
Jupiter
TestEngine API 구현체로 JUnit 5 를 제공한다.
Vintage
JUnit 4와 3을 지원하는 TestEngine 구현체이다.
JUnit 기본 어노테이션
@Test | 테스트 메소드임을 선언 JUnit Platform으로 실행된다. |
@BeforeAll | 테스트 클래스 안에 있는 테스트 메소드가 실행 전에 딱 한번 실행된다. |
@AfterAll | 테스트 클래스 안에 있는 테스트 메소드가 종료 후에 딱 한번 실행된다. |
@BeforeEach | 테스트 클래스 안의 각 테스트 메소드의 실행 전에 실행된다. |
@AfterEach | 테스트 클래스 안의 각 테스트 메소드의 종료 후에 실행된다. |
@Disabled | 이 테스트를 사용하지 않음을 표시한다. |
@DisplayNameGeneration | 메소드와 클래스 레퍼런스를 사용하여 테스트 이름을 표기하는 전략 설정 |
@DisplayName | 테스트 이름을 지정하는 어노테이션 |
Assertion
org.junit.jupiter.api.Assertions.*
assertEqulas(expected, actual) | 실제 값이 기대한 값과 같은지 확인 |
assertNotNull(actual) | 값이 null이 아닌지 확인 |
assertTrue(boolean) | 다음 조건이 참(true)인지 확인 |
assertAll(executables...) | 모든 확인 구문 확인 |
assertThrows(expectedType, executable) | 예외 발생 확인 |
assertTimeout(duration, executable) | 특정 시간 안에 실행이 완료되는지 확인 |
마지막 매개변수인 Supplier<String> 타입의 인스턴스를 람다 형태로 제공할 수 있다.
- 복잡한 메시지를 생성해야 하는 경우 사용하면 실패한 경우에만 해당 메시지를 만들게 할 수 있다.
JUnit 필요한거 추가하기
과제 1. live-study 대시 보드를 만드는 코드를 작성하세요
- 깃헙 이슈 1번부터 18번까지 댓글을 순화하며 댓글을 남긴 사용자를 체크 할 것
- 참여율을 계산하세요. 총 18회 중에 몇 %를 참여했는지 소숫점 두자리까지 보여줄 것
- Github 자바 라이브러리를 사용하면 편리합니다
- 깃헙 API를 익명으로 호출하는데 제한이 있기 때문에 본인의 깃헙 프로젝트에 이슈를 만들고 테스트를 하시면 더 자주 테스트할 수 있습니다
소스코드
import org.kohsuke.github.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LiveStudyDashBoard {
final String repo = "whiteship/live-study"; //레포지토리 명
final String token = "(Github token)"; //토큰 값
List<GHIssue> issues; //레포지토리에 있는 이슈들 저장
Map<String, boolean[]> participant; //참여자, 몇 주차(인덱스 역순)에 참여했는지 배열로 저장
public LiveStudyDashBoard() throws IOException {
this.issues = GitHub.connectUsingOAuth(token).getRepository(repo).getIssues(GHIssueState.ALL);
this.participant = savePartAndPartWeek();
}
public Map<String, boolean[]> savePartAndPartWeek() throws IOException {
Map<String, boolean[]> hm = new HashMap<>();
for (int i = 0; i < issues.size(); i++) {
for (GHIssueComment comment : issues.get(i).getComments()) {
String userLogin = comment.getUser().getLogin();
if (hm.containsKey(userLogin)) {
boolean[] weeks = hm.get(userLogin);
weeks[i] = true;
hm.put(userLogin, weeks);
}
else {
boolean[] newWeeks = new boolean[issues.size()];
newWeeks[i] = true;
hm.put(userLogin, newWeeks);
}
}
}
return hm;
}
public String drawFirstRow() {
String firstRow = "|";
for (int i = 0; i < issues.size(); i++) {
firstRow += "|" + (i+1) + "주차";
}
firstRow += "|출석률|\n|-";
for (int i = 0; i < issues.size(); i++) {
firstRow += "|-";
}
firstRow += "|-|\n";
return firstRow;
}
public String checkParticipationWeeksPerUser(String userLogin) {
boolean[] weeks = participant.get(userLogin);
String checkWeeks = "";
for (boolean isPartWeek : weeks) {
if (isPartWeek)
checkWeeks = "O|" + checkWeeks;
else
checkWeeks = "X|" + checkWeeks;
}
checkWeeks = "|" + checkWeeks;
return checkWeeks;
}
public double calcParticipationRatio(String userLogin) {
boolean[] weeks = participant.get(userLogin);
double partCnt = 0;
for (boolean isPartWeek : weeks) {
if (isPartWeek)
partCnt++;
}
return Math.round(partCnt / issues.size() * 10000) / 100D;
}
public String makeDashBoard() {
String dashBoard = drawFirstRow();
for (String userLogin : participant.keySet()) {
dashBoard += "|"
+ userLogin
+ checkParticipationWeeksPerUser(userLogin)
+ calcParticipationRatio(userLogin)
+ "|\n";
}
return dashBoard;
}
public static void main(String[] args) throws IOException {
LiveStudyDashBoard liveStudyDashBoard = new LiveStudyDashBoard();
System.out.println(liveStudyDashBoard.makeDashBoard());
}
}
생성된 문자열(Github 마크다운)
||1주차|2주차|3주차|4주차|5주차|6주차|7주차|8주차|9주차|10주차|11주차|12주차|13주차|14주차|15주차|16주차|17주차|18주차|출석률|
|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
|kimzerovirus|X|X|X|X|X|O|X|X|X|X|X|X|X|X|X|X|X|X|5.56|
|KwangJongJeon|O|O|O|X|O|O|O|O|O|O|O|O|X|X|X|X|X|X|61.11|
|jessi68|O|O|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|11.11|
|ufonetcom|O|O|O|O|O|X|X|X|X|X|X|X|X|X|X|X|X|X|27.78|
|JIN-096|O|O|O|O|O|O|O|O|O|O|O|O|X|X|X|X|X|X|66.67|
|ssonsh|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|X|O|X|88.89|
|Ohzzi|O|O|O|O|O|O|O|O|O|O|O|O|O|X|X|X|X|X|72.22|
|dongsub-joung|O|O|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|11.11|
|moo1o|O|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|5.56|
|Azderica|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|X|X|X|83.33|
|jymaeng95|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|X|X|X|83.33|
. . . . . .(이하 생략) . . . . . .
결과

과제 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란?
ListNode 구현
소스코드
public class ListNode {
ListNode nextNode;
int data;
public ListNode() {}
public ListNode(int data) {
this.data = data;
}
public static ListNode add(ListNode head, ListNode nodeToAdd, int position) {
ListNode tmp = head;
for (int i = 1; i < position; i++) {
tmp = tmp.nextNode;
if (tmp == null) {
System.out.println("범위를 초과하였습니다.");
return head;
}
}
tmp.nextNode = nodeToAdd;
return head;
}
public static ListNode remove(ListNode head, int positionToRemove) {
ListNode tmp = head;
ListNode pre = null;
for (int i = 1; i <=positionToRemove; i++) {
pre = tmp;
tmp = tmp.nextNode;
if (tmp == null) {
System.out.println("범위를 초과하였습니다.");
return head;
}
}
pre.nextNode = tmp.nextNode;
tmp = null;
return head;
}
public static boolean contains(ListNode head, ListNode nodeToCheck) {
boolean isContain = false;
while (head != null) {
if (head == nodeToCheck) {
isContain = true;
break;
}
head = head.nextNode;
}
return isContain;
}
}
테스트
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class ListNodeTest {
@Test
@DisplayName("add 함수 테스트")
void add() {
ListNode head = new ListNode();
ListNode node1 = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(3);
ListNode.add(head, node1, 1);
ListNode.add(head, node2, 2);
assertTrue(ListNode.contains(head, node1));
assertTrue(ListNode.contains(head, node2));
assertFalse(ListNode.contains(head, node3));
}
@Test
@DisplayName("remove 함수 테스트")
void remove() {
ListNode head = new ListNode();
ListNode node1 = new ListNode(1);
ListNode.add(head, node1, 1);
assertTrue(ListNode.contains(head,node1));
ListNode.remove(head,1);
assertFalse(ListNode.contains(head,node1));
}
@Test
@DisplayName("contains 함수 테스트")
void contains() {
ListNode head = new ListNode();
ListNode node1 = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(3);
ListNode.add(head, node1, 1);
ListNode.add(head, node2, 2);
assertTrue(ListNode.contains(head, node1));
assertTrue(ListNode.contains(head, node2));
assertFalse(ListNode.contains(head, node3));
}
}
과제 3. Stack을 구현하세요.
- int 배열을 사용해서 정수를 저장하는 Stack을 구현하세요.
- void push(int data)를 구현하세요.
- int pop()을 구현하세요.
소스코드
public class Stack {
public int top = -1;
public int size;
public int[] arr;
public Stack(int size) {
this.size = size;
this.arr = new int[size];
}
public void push(int data) {
if (isFull()) {
System.out.println("stack이 가득 찼습니다");
return ;
}
this.arr[++this.top] = data;
}
public int pop() {
if (isEmpty()) {
//에러처리 다시 짜기
System.out.println("stack이 비어있습니다.");
}
return this.arr[this.top--];
}
public boolean isFull() {
if (this.top == this.size-1)
return true;
return false;
}
public boolean isEmpty() {
if (this.top == -1)
return true;
return false;
}
}
테스트
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class StackTest {
@Test
void push() {
Stack s = new Stack(5);
for (int i=0; i<5; i++) {
s.push(i);
}
assertEquals(s.top, 4);
}
@Test
void pop() {
Stack s = new Stack(5);
for (int i=0; i<5; i++) {
s.push(i);
}
assertEquals(s.pop(), 4);
}
}
과제 4. 앞서 만든 ListNode를 사용해서 Stack을 구현하세요.
- ListNode head를 가지고 있는 ListNodeStack 클래스를 구현하세요.
- void push(int data)를 구현하세요.
- int pop()을 구현하세요.
소스코드
public class ListNodeStack {
public ListNode head;
public void push(int data) {
ListNode newNode = new ListNode(data);
if (head == null) {
head = newNode;
return;
}
ListNode tmp = head;
while (tmp.nextNode != null)
tmp = tmp.nextNode;
tmp.nextNode = newNode;
}
public int pop() {
ListNode tmp = head;
ListNode preNode = null;
while (tmp.nextNode != null) {
preNode = tmp;
tmp = tmp.nextNode;
}
preNode.nextNode = null;
return tmp.data;
}
}
테스트
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class ListNodeStackTest {
@Test
void push() {
ListNodeStack nodeStack = new ListNodeStack();
nodeStack.push(1);
nodeStack.push(2);
int cnt = 0;
while (nodeStack.head != null) {
nodeStack.head = nodeStack.head.nextNode;
cnt++;
}
assertEquals(cnt, 2);
}
@Test
void pop() {
ListNodeStack nodeStack = new ListNodeStack();
nodeStack.push(1);
nodeStack.push(2);
nodeStack.push(3);
nodeStack.push(4);
nodeStack.push(5);
assertEquals(nodeStack.pop(), 5);
assertEquals(nodeStack.pop(), 4);
}
}
과제 5. Queue를 구현하세요.
- 배열을 사용해서 한번
- ListNode를 사용해서 한번
배열
public class Queue {
int front = 0;
int rear = -1;
int size;
int[] arr;
public Queue(int size) {
this.size = size;
this.arr = new int[size];
}
public void push(int data) {
if (isFull())
return ;
arr[++rear] = data;
}
public int pop() {
if (!isEmpty())
return arr[front++];
return 0;
}
public boolean isEmpty() {
return front == rear + 1;
}
public boolean isFull() {
return size <= rear;
}
}
테스트
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class QueueTest {
@Test
void isEmpty() {
Queue q = new Queue(10);
assertTrue(q.isEmpty());
}
@Test
void isFull() {
Queue q = new Queue(1);
q.push(1);
assertTrue(q.isFull());
}
@Test
void push() {
Queue q = new Queue(10);
q.push(1);
int num = q.arr[0];
assertEquals(1, num);
}
@Test
void pop() {
Queue q = new Queue(10);
q.push(1);
q.push(2);
assertEquals(1, q.pop());
assertEquals(2, q.pop());
}
}
ListNode
public class ListNodeQueue {
ListNode head;
public void push(int data) {
ListNode newNode = new ListNode(data);
if (head == null) {
head = newNode;
return;
}
ListNode tmp = head;
while (tmp.nextNode != null)
tmp = tmp.nextNode;
tmp.nextNode = newNode;
}
public int pop() {
ListNode popNode = head;
ListNode nextNode = popNode.nextNode;
head = nextNode;
int tmp = popNode.data;
popNode = null;
return tmp;
}
}
테스트
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class ListNodeQueueTest {
@Test
void push() {
ListNode head = null;
ListNodeQueue nodeQueue = new ListNodeQueue();
nodeQueue.push(1);
nodeQueue.push(2);
int cnt = 0;
while (nodeQueue.head != null) {
nodeQueue.head = nodeQueue.head.nextNode;
cnt++;
}
assertEquals(2, cnt);
}
@Test
void pop() {
ListNodeQueue nodeQueue = new ListNodeQueue();
nodeQueue.push(1);
nodeQueue.push(2);
nodeQueue.push(3);
assertEquals(1, nodeQueue.pop());
assertEquals(2, nodeQueue.pop());
assertEquals(3, nodeQueue.pop());
}
}
'Java > java-live-study' 카테고리의 다른 글
백기선 자바 스터디 1기 6주차 (0) | 2022.05.12 |
---|---|
백기선 자바 스터디 1기 5주차 (0) | 2022.05.11 |
백기선 자바 스터디 1기 3주차 (0) | 2022.04.10 |
백기선 자바 스터디 1기 2주차 (0) | 2022.04.04 |
백기선 자바 스터디 1기 1주차 (0) | 2022.04.02 |