본 게시글은 백기선 님의 live-study 과제를 수행하면서 작성한 글입니다.
선택문(switch 문)
if 문의 경우 경우의 수가 많아질수록 계산해야 하는 조건식이 많아져 처리 시간이 오래 걸리며 가독성도 좋지 않을 수 있다.
이에 반해 Swtich 문은 하나의 조건식으로 많은 경우의 수를 처리할 수 있으며 표현도 간결하여 처리할 경우의 수가 많은 경우 Switch 문을 사용하는 것이 좋다.
switch 문은 조건식을 계산한 다음, 그 결과와 일치하는 case 문으로 이동 후 해당 case 문 아래에 있는 코드들을 실행하며 break 문을 만나면 switch 문을 빠져나가게 된다.
위 예시 코드를 보면 num 값은 2이기 때문에 (1) 과정에서 case 2:로 이동하여 (2) 과정에서 case 2: 아래에 있는 코드들을 실행하게 되고 case 3:에 있는 코드까지 실행하고 나서야 break 문을 만나 switch 문을 빠져나가게 된다.
조건식의 결과와 일치하는 값을 못 찾는 경우 default 문으로 이동하게 된다. if 문의 else 문과 같다고 생각하면 된다.
switch 문은 몇 개의 제약 조건이 있다.
- switch 문의 조건식 결과는 정수 또는 문자열
- case 문의 값은 정수 상수, 문자열 리터럴만 가능하며 중복 허용되지 않음. (JDK 1.7버전부터는 문자열 리터럴도 사용 가능)
final int NUM = 1;
int a = 0;
switch(조건식) {
case '5': // 문자 리터럴 '5'는 아스키 코드 값으로 53 정수이기 때문에 가능.
case NUM : // 정수 상수이기 때문에 가능.
case "Hi": // 문자열 리터럴은 JDK 1.7부터 가능.
case a: // 변수는 불가능
case 5.0: // 실수는 불가능
}
switch문도 if-else 문과 같이 중첩해서 사용 가능하다.
switch(조건식1) {
case 값1:
switch(조건식2) {
case 값11:
default:
}
case 값2:
default:
}
반복문
반복문은 특정 코드가 반복적으로 수행되도록 할 때 사용하며, 자바에서 반복문은 for 문, while 문, do-while 문이 있다.
for문
for(초기화; 조건식; 증감식;) {
// 반복할 코드
}
- 초기화 : 반복문에 사용될 변수를 초기화하는 부분으로 처음 한 번만 수행된다.
- 조건식 : 조건식의 값이 true 이면 반복문을 계속해서 실행하고 false 이면 실행을 중단하고 빠져나간다.
- 증감식 : 반복문을 제어하는 변수의 값을 증가시키거나 감소시키는 부분으로 증감식에 의해서 값이 변화하여 조건식이 false가 되면 반복문을 빠져나가게 된다.
// for문 예시
for(int i = 0; i < 5; i++) {
System.out.print(i + " ");
}
// 결과 : 0 1 2 3 4
예를 들어 다음과 같은 반복문이 있다면 초기화 부분에서 변수 i는 0으로 초기화되고 반복 시마다 i의 값은 1씩 증가하고, 계속되는 반복 과정에서 i < 5 조건식의 결과가 false가 되면 반복을 중단하게 된다.
향상된 for문(JDK 1.5 버전 이상)
JDK 1.5부터 배열이나 컬렉션의 요소에 기존보다 편리하게 접근할 수 있도록 새로운 for 문이 추가되었다.
for(타입 변수명 : 배열 or 컬렉션) {
// 반복할 코드
}
타입은 배열 또는 컬렉션의 타입이어야 하며, 배열 또는 컬렉션에 있는 값들이 순차적으로 매 반복마다 변수명으로 지정한 변수에 저장되어 {} 안의 코드에서 사용할 수 있게 된다.
int arr[] = {1,2,3,4,5};
for(int n : arr) {
System.out.print(n + " ");
}
// 결과 : 1 2 3 4 5
while 문
while(조건식) {
// 반복할 코드
}
while문은 조건의 결과가 false가 될 때까지 반복한다.
// for문과 while문의 비교
// for문
for(int i = 0; i < 5; i++) {
System.out.println(i);
}
// while문
int i = 0;
while(i < 5) {
System.out.println(i++);
}
do-while문
do {
// 반복할 코드
} while(조건식)
do-while 문은 while과 구조가 비슷하지만 최초 반복문의 실행 시부터 조건을 검사하는 while 문과 달리 반복할 코드를 먼저 수행하고 그다음에 조건을 검사한다.
결과적으로 while 문은 조건식의 결과에 따라 반복문이 한 번도 실행되지 않을 수 있지만 do-while 문은 반복문이 최소 한 번은 실행된다.
continue문
continue 문은 반복문 내에서만 사용되며, continue 문을 만나면 나머지 코드를 실행하지 않고 해당 반복문의 끝으로 이동하여 다음 반복을 넘어간다.
break 문
break 문은 앞서 보았듯이 switch 문과 반복문 내에서 사용할 수 있으며, 반복문에서 사용 시 자신이 포함된 가장 가까운 반복문을 빠져나가게 된다.
과제 0. JUnit 5 학습하세요.
과제1 live-study 대시 보드를 만드는 코드를 작성하세요.
import org.kohsuke.github.*;
import java.io.IOException;
import java.util.*;
public class App {
public static void main(String[] args) throws IOException {
GitHub gitHub = new GitHubBuilder().withOAuthToken(MY_TOKEN).build();
GHRepository repo = gitHub.getRepository("whiteship/live-study");
List<GHIssue> issues = repo.getIssues(GHIssueState.ALL);
HashMap<String, Integer> userInfo = new HashMap<>();
for (GHIssue issue : issues) {
List<GHIssueComment> comments = issue.getComments();
for(GHIssueComment comment : comments) {
String userName = comment.getUser().getName();
if (comment.getUser().getName() != null) {
userInfo.put(userName, userInfo.getOrDefault(userName, 0) + 1);
}
}
}
for(String username : userInfo.keySet()) {
System.out.printf( "%s : %.2f%%\n", username, (float)userInfo.get(username)/issues.size()*100);
}
}
}
과제 2. LinkedList를 구현하세요.
연결리스트(Linked List)란?
연결 리스트는 데이터 다음 요소를 가리키는 포인터로 이루어진 노드들이 연결된 형태로 구성되어 있는 자료구조이다.
연결리스트와 배열의 비교
배열
- 데이터를 연속적인 메모리 공간에 순차적으로 저장한다.
- 인덱스를 가지고 있기 때문에 데이터 접근 속도가 빠르다.
- 데이터를 삽입 또는 삭제하는 경우, 삽입 또는 삭제를 수행한 위치로부터 다음에 있는 모든 요소들의 위치를 변경해야 하기 때문에 비효율적이다.
연결리스트
- 데이터를 불연속적인 공간에 순차적으로 저장한다.
- 배열과 달리 인덱스는 없고 현재 노드의 다음이나 이전 위치 포인터를 가지고 있다.
- 데이터에 접근하려면 헤드 노드부터 하나씩 순차적으로 접근해 나가야 하므로 배열에 비해 비효율적이다.
- 데이터의 삽입 또는 삭제는 삽입 또는 삭제하고자 하는 위치의 노드들을 연결해 주기만 하면 되므로 배열에 비해 효율적이다.
연결리스트 구현
- 정수를 저장하는 ListNode 클래스구현.
- ListNode add(ListNode head, ListNode nodeToAdd, int position)를 구현.
- ListNode remove(ListNode head, int positionToRemove)를 구현.
- boolean contains(ListNode head, ListNode nodeTocheck)를 구현.
public class ListNode {
public ListNode(int data) {
this.data = data;
this.nextNode = null;
}
int data;
ListNode nextNode;
public static ListNode add(ListNode head, ListNode nodeToAdd, int position) {
if (position == 0) {
nodeToAdd.nextNode = head.nextNode;
head.nextNode = nodeToAdd;
return nodeToAdd;
}
ListNode curNode = head;
for(int i = 0; i < position; i++) {
if (curNode.nextNode == null) {
return null;
}
curNode = curNode.nextNode;
}
nodeToAdd.nextNode = curNode.nextNode;
curNode.nextNode = nodeToAdd;
return nodeToAdd;
}
public static ListNode remove(ListNode head, int positionToRemove) {
if (positionToRemove == 0) {
head.nextNode = head.nextNode.nextNode;
return head.nextNode;
}
ListNode curNode = head;
for (int i = 0; i < positionToRemove; i++) {
if (curNode.nextNode == null) {
return null;
}
curNode = curNode.nextNode;
}
ListNode removeNode = curNode.nextNode;
curNode.nextNode = removeNode.nextNode;
return removeNode;
}
public static boolean contains(ListNode head, ListNode nodeToCheck) {
boolean isContains = false;
ListNode curNode = head;
while(curNode.nextNode != null) {
curNode = curNode.nextNode;
if (curNode == nodeToCheck) {
return true;
}
}
return false;
}
public static void printList(ListNode head) {
ListNode curNode = head;
System.out.print("[");
while(curNode.nextNode != null) {
curNode = curNode.nextNode;
System.out.print(curNode.data + ", ");
}
System.out.print("]");
System.out.println();
}
}
과제 3. Stack을 구현하세요.
- int 배열을 사용해서 정수를 저장하는 Stack을 구현하세요.
- void push(int data)를 구현하세요.
- int pop()을 구현하세요.
public class ArrayStack {
private int size;
private int[] arr;
private int curPos;
public ArrayStack() {
this(10);
}
public ArrayStack(int size) {
this.size = size;
this.arr = new int[size];
this.curPos = -1;
}
public void push(int data) {
if (curPos == size-1) {
int[] temp = new int[size + size/2];
System.arraycopy(this.arr, 0, temp, 0, size);
this.arr = temp;
this.size += (size/2);
}
arr[++curPos] = data;
}
public int pop() {
if (isEmpty()) {
System.out.println("Stack is empty!!");
return -1;
}
return arr[curPos--];
}
public boolean isEmpty() {
return curPos == -1;
}
public void printStack() {
if (curPos == -1) {
System.out.println("[ ]");
return;
}
System.out.print("[");
for (int i = 0; i <= curPos; i++) {
System.out.print(arr[i] + ", ");
}
System.out.print("]");
System.out.println();
}
}
과제 4. 앞서 만든 ListNode를 사용해서 Stack을 구현하세요.
- ListNode head를 가지고 있는 ListNodeStack 클래스를 구현하세요.
- void push(int data)를 구현하세요.
- int pop()을 구현하세요.
public class LinkedListStack {
ListNode head;
public LinkedListStack() {
this.head = new ListNode(-1);
}
public void push(int data) {
ListNode.add(this.head, new ListNode(data), 0);
}
public int pop() {
ListNode removeNode = ListNode.remove(this.head, 0);
if (removeNode == null) {
System.out.println("Stack is empty!!");
return -1;
} else {
return removeNode.data;
}
}
public void print() {
ListNode.printList(this.head);
}
public boolean isEmpty() {
return this.head.nextNode == null;
}
}
과제 5. Queue를 구현하세요.
- 배열을 사용해서 한번
- ListNode를 사용해서 한번.
ArrayQueue
public class ArrayQueue {
int[] arr;
int frontPos;
int rearPos;
public ArrayQueue() {
this(10);
}
public ArrayQueue(int size) {
arr = new int[size+1];
frontPos = 0;
rearPos = 0;
}
public void offer(int data) {
if (getNextPos(rearPos) == frontPos) {
System.out.println("Queue is full!");
return;
}
rearPos = getNextPos(rearPos);
arr[rearPos] = data;
}
public int poll() {
if (isEmpty()) {
System.out.println("Queue is empty!!");
return -1;
}
frontPos = getNextPos(frontPos);
return arr[frontPos];
}
public boolean isEmpty() {
return frontPos == rearPos;
}
public int peek() {
if (isEmpty()) {
System.out.println("Queue is empty!!");
return -1;
}
return arr[getNextPos(frontPos)];
}
private int getNextPos(int pos) {
if (pos == arr.length-1) {
return 0;
} else {
return ++pos;
}
}
}
LinkedListQueue
public class LinkedListQueue {
ListNode head;
ListNode tail;
public LinkedListQueue() {
head = new ListNode(-1);
tail = head;
}
public void offer(int data) {
ListNode newNode = new ListNode(data);
tail.nextNode = newNode;
tail = newNode;
}
public int poll() {
if (isEmpty()) {
System.out.println("Queue is empty!!");
return -1;
}
head = head.nextNode;
return head.data;
}
public int peek() {
if (isEmpty()) {
System.out.println("Queue is empty!!");
return -1;
}
return head.nextNode.data;
}
public boolean isEmpty() {
return head.nextNode == null;
}
}
참고
- 윤성우의 열혈 자료구조
- 자바의 정석 3판(남궁성 저)
'자바 > 스터디' 카테고리의 다른 글
[자바 스터디] 5주차 과제 - 클래스 (0) | 2020.12.17 |
---|---|
[스터디] JUnit5 자바 단위 테스트 프레임워크 (0) | 2020.12.14 |
[자바 스터디] 3주차 과제 : 연산자 (0) | 2020.12.01 |
[자바 스터디] 2주차 과제 : 자바 데이터 타입, 변수 그리고 배열 (0) | 2020.11.21 |
[자바 스터디] 1주차 과제: JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가 (0) | 2020.11.18 |
댓글