💡 목표 : 자바가 제공하는 제어문을 학습하자.
⚡️ 목차
- 선택문
- 반복문
⚡️ 과제
- LinkedList 구현하기
- ListNode add(ListNode head, ListNode nodeToAdd, int position)를 구현하기.
- ListNode remove(ListNode head, int positionToRemove)를 구현하기.
- boolean contains(ListNode head, ListNode nodeTocheck)를 구현하기.
- Stack 구현하기
- void push(int data)를 구현하기.
- int pop()을 구현하기.
- 앞서 만든 ListNode를 사용해서 Stack을 구현하기
- void push(int data)를 구현하기.
- int pop()을 구현하기.
- Queue 구현하기
- 배열을 사용해서 한번.
- ListNode를 사용해서 한번.
Java에서 코드는 위에서 아래 순으로 읽고 실행된다. 모든 일을 순차적으로 실행 할 수 있다면 아무런 상관이 없겠지만, 어떤 코드를 반복해야 될 수도 있고 어떤 코드는 건너뛰는 등 순서를 변경해야 되는 일이 발생한다. 이 때, 제어문을 사용하여 코드 실행 흐름을 제어 할 수 있다. 이러한 제어문은 선택문(if, if-else, switch)과, 반복문 (for, while, do-while)으로 나뉜다.
if문은 가장 기본적인 제어문 중 하나로 지정한 조건이 만족할 시에 지정한 블록({}
) 안에 있는 코드가 실행된다
if (조건식) { //코드가 한 줄일 경우 {} 생략 가능
조건이 참일 경우 실행되는 코드;
}
기본적인 if문에서는 참일 경우에만 실행이 됐다면, if-else문은 거짓일 때도 실행할 수 있다. 즉, 조건식이 참일 경우와 거짓일 경우의 실행되는 코드들을 나눌 수 있다는것.
if (조건식) {
참일 경우;
} else if (조건식) {
또 다른 조건이 참일 경우;
} else {
거짓일 경우 (= 모든 조건에 부합하지 않을 경우);
}
이렇게 조건이 하나만 존재 할 수 있지만, 여러가지의 조건을 사용해야 할 경우가 있다. (예 : 성적) 이때는 else-if()를 사용하여 또 다른 조건식을 사용할 수 있다.
switch문은 if문과 if-else문과 다르게 변수가 어떤 값을 가지느냐에 따라 실행문이 선택된다. if문은 조건식의 결과가 true, false 두가지 밖에 없기 때문에 경우의 수가 많아질수록 else-if문을 반복적으로 추가 해야하므로 코드가 복잡해진다. 그러나 switch문은 변수의 값에 따라서 실행문이 결정되기 때문에 같은 기능의 if문보다 코드가 간결하다.
switch(변수) {
case 값1 :
// 변수가 값1일 경우 실행
break;
case 값2 :
// 변수가 값2일 경우 실행
break;
defalut :
// 변수가 값1, 값2 모두 아닐 경우 실행
break;
위 예시는 if-else문으로 변경 가능하다
if (변수 == 값A ) {
// 변수가 값 A에 해당하는 경우;
} else-if (변수 == 값B) {
// 변수가 값 B에 해당하는 경우;
} else {
// 어떠한 값도 해당하지 않는 경우;
}
어떠한 코드가 반복적으로 사용될 때 사용되는 구문이다.
프로그래머가 설정한 조건이 만족할 때 까지 지정한 코드 블럭이 반복적으로 수행된다. 카운팅을 할 수도 있겠지만, 배열 혹은 컬렉션 안에 저장되어 있는 값을 순회 할 때도 많이 사용된다.
for (초기식; 조건식; 증감식) {
반복 될 코드;
}
JDK 5.0 이상부터 배열 혹은 컬렉션의 순회시에 다음과 같이 향상된 for문을 사용할 수 있다.
for (타입과 변수명 : 배열 or 컬렉션) {
반복 될 코드;
}
//foreach 스타일 for문 : 어떤 컬렉션이든 순회할 수 있음.
Effective java-item 46 : for문 보다 for-each문을 사용하라 for-each문은 반복자나 인덱스 변수를 제거해 오류 가능성을 줄일 수 있다.
for문이 정해진 횟수만큼 반복한다면, while문은 특정 조건이 성립(true)할 때 까지 계속해서 반복한다.
while (조건식) { //false일 경우 조건식을 빠져 나간다
조건식이 참일 경우 실행 될 코드;
}
조건식이 항상 참일 경우에는 해당 코드들이 실행되므로 다음 명령을 수행할 수 없는 상태가 된다. (=무한루프) 조건식을 유의해서 사용하자
while문은 조건식을 먼저 판별하고 코드를 수행했다면, do-while문은 먼저 코드블럭을 실행하고 조건을 판별한다.
do {
1. 조건식이 참일 경우 실행되는 코드;
} while (2.조건식);
do-while문은 do의 실행문을 먼저 우선 실행하고 조건식을 평가하는데, 그 결과가 true라면 1 -> 2와 같이 반복 실행을 하고 결과가 false라면 do-while문을 종료한다. 이 때 주의할 점은 while()문 뒤에 반드시 세미콜론(;
)을 붙여야 한다.
public class ListNode {
private int data;
private ListNode next;
public ListNode(int data) {
this.data = data;
}
public void add(ListNode newData) {
if (this.next == null) {
this.next = newData;
}
ListNode nextNode = this.next;
while (nextNode.next != null) {
nextNode = nextNode.next;
}
nextNode.next = newData;
}
public void add(ListNode head, ListNode nodeToAdd, int position) {
ListNode nextNode = head;
for (int i = 0; i < position-1; i++) {
if (nextNode.next == null) {
nextNode.next = nodeToAdd;
break;
}
nextNode = nextNode.next;
}
nodeToAdd.next = nextNode.next;
nextNode.next = nodeToAdd;
}
public void remove(ListNode head, int positionToRemove) {
ListNode nextNode = head;
for (int i = 1; i < positionToRemove-1; i++) {
if (nextNode.next.next == null) {
break;
}
nextNode = nextNode.next;
}
nextNode.next = nextNode.next.next;
}
public boolean contains(ListNode head, ListNode nodeToCheck) {
ListNode temp = head;
while (temp.next != null) {
if (temp.equals(nodeToCheck) {
return ture;
}
temp = temp.next;
}
return false;
}
}
public class Stack<T> {
private List<Integer> stack = new ArrayList<>();
public void push(int data) {
stack.add(data);
}
public int pop() {
if (stack.isEmpty()) {
return -1;
}
return stack.remove(stack.size() - 1);
}
}
public class ListNodeStack {
private ListNode node = null;
private ListNode head;
public void push(int data) {
if (node == null) {
node = new ListNode(data);
head = node;
return;
}
ListNode nextNode = node.next;
while (nextNode.next != null) {
nextNode = nextNode.next;
}
nextNode.next = new ListNode(data);
head = nextNode.next;
}
public int pop() {
if (head == null) {
throw new EmptyStackException();
}
ListNode preNode = node;
while (preNode.next == head) {
preNode = preNode.next;
}
preNode.next = null;
int popResult = head.data;
head = preNode;
return popResult;
}
}
public class Queue {
private List<Integer> queue = new ArrayList<>();
public void enqueue(int data) {
list.add(data);
}
public Integer dequeue() {
if(queue.isEmpty()) {
throw new NoSuchElementException();
}
return list.remove(0);
}
}
public class ListNodeQueue {
private ListNode queue = null;
private ListNode head;
public void enqueue(int data) {
if (queue == null) {
queue = new ListNode(data);
head = queue;
return;
}
queue.next = new ListNode(data);
queue = queue.next;
}
public void dequeue() {
int originHead = head.data;
head = head.next;
return originHead;
}
}