일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 백준#BOJ#8012#한동이는영업사원
- 백준#BOJ#1939#중량제한
- 백준#BOJ#14501#퇴사#브루트포스
- 백준#BOJ#12865#평범한배낭
- 백준#boj#12755
- 백준#BOJ#2615#오목
- 백준#boj#16932#모양만들기
- Today
- Total
순간을 성실히, 화려함보단 꾸준함을
4주차 과제: 제어문 본문
목표
자바가 제공하는 제어문을 학습하세요.
학습할 것 (필수)
- 선택문과
- 조건문
- 반복문
과제 (옵션)
- 과제 0. JUnit 5 학습하세요.
- 과제 1. live-study 대시 보드를 만드는 코드를 작성하세요.
- 과제 2. LinkedList를 구현하세요.
- 과제 3. Stack을 구현하세요.
- 과제 4. 앞서 만든 ListNode를 사용해서 Stack을 구현하세요
- 과제 5. Queue를 구현하세요.
제어문이란
프로그램의 실행 흐름을 실행자가 원하는 방향으로 바꾸어 줄 수 있게끔 해주는 것.
일반적으로 조건식과 실행 구문인 중괄호로 구성이 되어있다.
1.조건문
명령문 또는 명령문 블록의 실행 여부를 결정해 주는 역할을 수행합니다.
조건이 참이면 블록문의 코드들을 실행하게 되고 그렇지 않으면 블록을 건너 뜁니다.
if(condition){
//statement
}else if(condition){
//statement
}else{
//statement
}
2. 선택문이란
조건에 따라 명령을 처리하는 문법을 뜻합니다. 대표적으로 switch문이 있습니다.
if 문과 유사한 기능을 수행하며 if문보다 더 빠른 성능을 가지고 있습니다.
public class Main{
public static void main(String[] args){
int x=3;
switch(x){
case 1:
System.out.println("x : " + x);
break;
case 2:
System.out.println("x : " + x);
break;
case 3:
System.out.println("x : " + x); //3 출력
break;
case 4 :
System.out.println("x : " + x);
break;
default:
System.out.println("x : " + x);
break;
}
}
}
switch문의 특징 중 하나는 break 키워드를 적어주지 않는다면 루프문을 빠져나오지 않고 계속 실행된다는 점이다. 이 때문에 다양한 입력값이 들어오더라도 같은 결과값을 리턴시켜줄 수 있다.
public class Main{
public static void main(String[] args){
int x=3;
switch(x){
case 1:
System.out.println("x : 1" );
break;
case 2:
System.out.println("x : 2");
break;
case 3:
System.out.println("x : 3"); //3 출력
//break;
case 4 :
System.out.println("x : 4"); //4 출력
break;
default:
System.out.println("x : default");
break;
}
}
}
case 조건에 맞지 않는 입력값이 들어온다면 default 조건의 구문을 실행합니다.
public class Main{
public static void main(String[] args){
int x=10;
switch(x){
case 1:
System.out.println("x : 1" );
break;
case 2:
System.out.println("x : 2");
break;
case 3:
System.out.println("x : 3");
break;
case 4 :
System.out.println("x : 4");
break;
default:
System.out.println("x : default"); //default 출력
break;
}
}
}
주의할 점은 default는 case 조건에 맞지 않은 모든 예외 입력값들이 해당되니 맨 마지막에 적어주시는 것이 좋습니다.
더불어 break을 단 한개도 적어주지 않고 모든 구문을 실행하는 것을 풀 스루(full-through) 라고 합니다.
3. 반복문이란
일정한 조건에 벗어나기 전까지 정의되어 있는 구문을 반복적으로 실행하는 문법을 뜻합니다.
대표적으로 for, while 문이 존재합니다.
public class Main{
public static void main(String[] args){
int sum=0;
for(int i=0;i<10;i++)
sum+=i;
System.out.println("sum : " + sum);
}
}
0부터 9까지의 수를 더하는 작업입니다. i
변수가 10이 되는 시점에 반복문을 벗어나게 됩니다.
public class Main{
public static void main(String[] args){
int sum=0,i=0;
while(i<10){
sum+=i;
i++;
}
System.out.println("sum : "+sum);
}
}
for 문으로 작성한 반복문을 while문으로 작성한 코드입니다. 동일한 결과값을 도출하지만 while 문은 만약 ()
안의 조건이 true
라면 무한반복을 실행하게 됩니다. 이를 주의하셔야 합니다.
JUnit 5 란?
자바 개발자가 가장 많이 사용하는 테스팅 프래임워크를 의미합니다.(단위 테스트를 작성하는 개발자의 93%가 Junit5를 사용합니다)
자바8 이상의 환경에서 요구됩니다.
JUnit 4 가 단일 jar였던 것에 비해, JUnit 5 는 크게 JUnit Platform, Jupiter,Vintage 모듈로 구성되어 있습니다.
왜 Jnuit 5 를 개발하였을까?
- IDE에 대한 강한 결합도를 해결하기 위해
- 부족했던 확장성을 해결하기 위해
->하나의 @Runwith에 여러 Rule을 사용하여 확장하고, Runwith들이 결합되지 못했었습니다. - 하나의 Jar에 포함되어 있던 코드를 분리하기 위해
Platform : 테스트를 실행해주는 런처를 제공. TestEngine API 제공
-> 테스트를 발견하고 계획을 생성하는 TestEngine 인터페이스를 정의하고 이를 통해 테스트를 발견,실행,결과를 보고합니다.
Jupiter : TestEngine API 구현체로 JUnit 5를 제공
->TestEngine의 실제 구현체는 별도의 모듈로 존재하는데, 이 모듈 중 하나가 Jupiter-Engine 입니다.Jupiter-API 를 사용해서 작성한 테스트 코드를 발견하고 실행합니다.
Vintage : JUnit 4와 3를 지원하는 TestEngine 구현체
기본 에노테이션
- @Test : test를 실행할 코드이다.
- @BeforeAll / @AfterAll : @BeforeAll 은 모든 Test를 실행하기 전 딱 한번만 실행하고 , @AfterAll 은 모든 Test를 실행하고 난 후 딱 한번만 실행한다.
- @BeforeEach / @AfterEach : @BeforeEach는 각 Test를 실행하기 전마다 실행하고, @AfterEach 은 각 Test를 실행한 후 마다 실행한다.
- @Disabled : 원하는 Test를 실행하지 못하게끔 해준다.
package com.example.demo;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.test.context.TestExecutionListeners;
import static org.junit.jupiter.api.Assertions.*;
class StudyTest {
@Test
//이제 public을 붙일 필요가 없어졌다
void create(){
Study study = new Study();
assertNotNull(study);
System.out.println("create");
}
@Test
void create1(){
System.out.println("create1");
}
//모든 테스트가 실행되기 전 이전에 딱 한번만 실행
//반드시 static method 사용,return type이 있으면 안된다
//그냥 반드시 static void 로 작성해야된다고 생각
@BeforeAll
static void beforeAll(){
System.out.println("before all");
}
//모든 테스트가 실행 된 이후에 딱 한번만 실행
@AfterAll
static void afterAll(){
System.out.println("after all");
}
//각 Test실행이 일어나기전에 실행된다.
//따라서 반드시 static이 아니어도 된다.
@BeforeEach
void beforeEach() {
System.out.println("before each");
}
}
//출력
before all
before each
create
before each
create1
after all
나머지 내용은 글의 취지에 맞지 않아 그냥 스킵하겠습니다.(후에 JUnit 5 관한 글들을 업로드 하겠습니다)
과제1.live-study 대시 보드를 만드는 코드를 작성하세요.
- 깃헙 이슈 1번부터 15번까지 댓글을 순회하며 댓글을 남긴 사용자를 체크 할 것.
- 참여율을 계산하세요. 총 15회에 중에 몇 %를 참여했는지 소숫점 두자리가지 보여줄 것.
이 두가지를 구현하는 프로그램을 작성하는 것 이었습니다.
링크를 참조
package main.java;
import org.kohsuke.github.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
public class Main {
static private int COUNT = 15;
public static void main(String[] args) throws IOException {
//암호를 통해서 깃에 연결
//이때 my_token 은 문자열 my_token 이 아닌 깃에서 생성하여 주어진 토큰을 사용해야 합니다.
GitHub gitHub = new GitHubBuilder().withOAuthToken("my_token").build();
//해당 레파지토리에 연결
GHRepository ghRepository = gitHub.getRepository("Lee-Seong-Ju/live-study").getSource();
//레파지토리의 존재하는 이슈들을 list에 담음
List<GHIssue> ghIssues = ghRepository.getIssues(GHIssueState.ALL);
//참석자의 정보를 담을 수 있는 hashmap 생성
HashMap<String,Integer> state = new HashMap<String, Integer>();
for(GHIssue ghIssue : ghIssues){
//한사람이 두개 이상의 댓글을 달 수 있으니 중복 제거하기 위해 set 선언
HashSet<String> participate = new HashSet<>();
for(GHIssueComment comments : ghIssue.getComments())
participate.add(comments.getUser().getName());
//set에 담겨져 있는 이름들을 확인하고 count 시켜줌
for(String name : participate) {
if(state.containsKey(name))
state.replace(name,state.get(name)+1);
else
state.put(name,1);
}
}
//참석자와 참석율 출력
state.forEach((key,value)->{
double percent = (double)(value*100)/state.size();
System.out.println("참여자명 : " + key);
System.out.println("참석율 : " + String.format("%.2f",percent)+"%");
});
}
}
//출력문
참여자명 : 이창섭
참석율 : 3.64%
참여자명 : wony9324
참석율 : 4.73%
참여자명 : sseung
참석율 : 1.09%
참여자명 : MaengSol
참석율 : 2.18%
참여자명 : CHAE JEONG LEE
참석율 : 0.36%
참여자명 : Heewon Gwak
참석율 : 1.82%
참여자명 : TaeJeong Kim
참석율 : 2.18%
참여자명 : JBB
참석율 : 0.36%
참여자명 : YOONJU EOM
참석율 : 1.45%
참여자명 : Bae Sangwoo
참석율 : 5.82%
참여자명 : yeji an
참석율 : 3.64%
참여자명 : YuSeungMo
참석율 : 4.36%
참여자명 : Bikoo
참석율 : 1.09%
.........
전 백기선님의 live-study 레포를 fork 하여 가져왔습니다. 이때 fork 를 하였을땐 그냥 GHRepository ghRepository = gitHub.getRepository("Lee-Seong-Ju/live-study")
이것만 적었을땐 오류가 발생합니다.
이유는 fork를 하였다고 하더라도 이슈는 백기선님의 레포에 연결이 되어있기 때문이죠.
따라서 후에 getSource()
를 붙여주셔야 합니다.
과제 2. LinkedList를 구현하세요.
package com.example.demo;
public class Node {
int data;
Node nextNode;
public Node(int data){
this.nextNode=null;
this.data=data;
}
public Node add(Node head,int data){
Node new_node = new Node(data);
Node tmp = head;
while(tmp.nextNode!=null)
tmp = tmp.nextNode;
tmp.nextNode=new_node;
return head;
}
public Node remove(Node head,int data){
Node pre_node = head;
Node cur_node=head.nextNode;
if(head.data==data) {
head = cur_node;
pre_node=null;
}else{
while(cur_node!=null){
if(cur_node.data==data){
if(cur_node.nextNode==null)
pre_node.nextNode = null;
else
pre_node.nextNode = cur_node.nextNode;
cur_node=null;
break;
}
pre_node = cur_node;
cur_node = cur_node.nextNode;
}
}
return head;
}
public boolean contains(Node head,int data){
Node tmp = head;
while(tmp!=null){
if(tmp.data==data)
return true;
tmp = tmp.nextNode;
}
return false;
}
}
TESTCODE
package com.example.demo;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class NodeTest {
Node head=null;
void printNode(){
Node tmp = head;
while(tmp!=null){
System.out.println(tmp.data);
tmp = tmp.nextNode;
}
}
@Test
@Order(2)
void addTest(){
head = head.add(head,2);
head = head.add(head,3);
head = head.add(head,4);
System.out.println("ADD : 2,3,4");
printNode();
}
@Test
@Order(3)
void removeTest(){
head = head.remove(head,2);
head = head.remove(head,3);
System.out.println("REMOVE : 2,3");
printNode();
}
@Test
@Order(4)
void containsTest(){
System.out.println("CONTAIN : 1,4");
System.out.println(head.contains(head,1));
System.out.println(head.contains(head,4));
}
@BeforeAll
@Order(1)
void set_up(){
head = new Node(1);
System.out.println("CREAT : 1");
printNode();
}
}
추가로 설명해야 될 부분은@TestInstance(TestInstance.Lifecycle.PER_CLASS)
와 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
인데 이 부분은 후에 JUnit 5 에 관해 글을 다시 올리겠습니다.(저도 공부중이라서요,,,)
간단하게 설명을 하자면@TestInstance(TestInstance.Lifecycle.PER_CLASS)
이 어노테이션은 매 @Test
마다 새롭게 변수들이 업로드 되어 초기화 되는 것을 막아주는 역할을 수행합니다.
그리고 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
이 어노테이션은 테스트마다 순서를 부여하여 수행을 할 수 있게끔 해줍니다.
과제3. Stack을 구현하세요.
package com.example.demo;
public class Node {
int []stack;
int top;
public Node(int size){
stack = new int[size];
top=-1;
}
public void push(int data){
stack[++top]=data;
}
public int pop(){
int ret=stack[top];
stack[top--]=0;
return ret;
}
public void printStack(){
for(int i=0;i<=top;i++)
System.out.println(stack[i]);
}
}
TESTCODE
package com.example.demo;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class NodeTest {
Node head;
@BeforeAll
void beforeAll(){
head = new Node(10);
}
@Test
@Order(1)
void push(){
head.push(1);
head.push(2);
head.push(3);
System.out.println("push : 1,2,3");
head.printStack();
}
@Test
@Order(2)
void pop(){
System.out.println("pop : 3,2");
System.out.println(head.pop());
System.out.println(head.pop());
}
}
과제4. 앞서 만든 ListNode를 사용해서 Stack을 구현하세요
package com.example.demo;
class Node {
int data;
Node nextnode;
public Node(int data){
this.data=data;
this.nextnode=null;
}
}
public class ListStack{
Node head=null;
Node node;
public void push(int data){
node = new Node(data);
if(head==null){
head=node;
}else {
Node tmp = head;
while (tmp.nextnode != null)
tmp = tmp.nextnode;
tmp.nextnode = node;
}
}
public int pop(){
Node prenode=null;
Node tmp = head;
while(tmp.nextnode!=null) {
prenode=tmp;
tmp = tmp.nextnode;
}
prenode.nextnode=null;
int ret = tmp.data;
tmp=null;
return ret;
}
public void printStack(){
Node tmp = head;
while(tmp!=null){
System.out.println(tmp.data);
tmp=tmp.nextnode;
}
}
}
TESTCODE
package com.example.demo;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class ListStackTest {
ListStack list = new ListStack();
@Test
@Order(1)
void push(){
list.push(1);
list.push(2);
list.push(3);
list.push(4);
System.out.println("push : 1,2,3,4");
list.printStack();
}
@Test
@Order(2)
void pop(){
System.out.println("pop : 4,3");
System.out.println(list.pop());
System.out.println(list.pop());
}
}
과제 5. Queue를 구현하세요.(ListQueue)
package com.example.demo;
public class ListQueue {
Node head;
public void push(int data){
if(head==null){
head=new Node(data);
}else{
Node tmp = head;
while(tmp.nextnode!=null)
tmp=tmp.nextnode;
tmp.nextnode=new Node(data);
}
}
public int pop(){
Node tmp = head;
head=head.nextnode;
int ret=tmp.data;
tmp=null;
return ret;
}
public void printQueue(){
Node tmp = head;
while(tmp!=null){
System.out.println(tmp.data);
tmp = tmp.nextnode;
}
}
}
class Node{
int data;
Node nextnode;
public Node(int data){
this.data=data;
nextnode=null;
}
}
TESTCODE
package com.example.demo;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class ListQueueTest {
ListQueue queue = new ListQueue();
@Test
@Order(1)
void push(){
queue.push(1);
queue.push(2);
queue.push(3);
System.out.println("push : 1,2,3");
queue.printQueue();
}
@Test
@Order(2)
void pop(){
System.out.println("pop : 1,2");
System.out.println(queue.pop());
System.out.println(queue.pop());
}
}
'백기선님과 함께 하는 자바 스터디' 카테고리의 다른 글
5주차 과제 : 추가사항 (0) | 2021.06.06 |
---|---|
5주차 과제: 클래스 (0) | 2021.06.06 |
3주차 과제: 연산자 (0) | 2021.05.16 |
2주차 과제: 자바 데이터 타입, 변수 그리고 배열 (0) | 2021.05.05 |
1주차 : JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가? (4) | 2021.05.01 |