public static void main(String[] args) {
// 방법 1 (기본) : for (초기화식; 조건식; 증감식) → 조건식의 결과가 참인 동안 반복적으로 실행
for (int i=1; i<=10; i++) {
System.out.println(i); // i 는 1~10 까지 출력
}
// 방법 2 : 초기화식이 필요 없을 경우, 생략 가능
for (; i<=10; i++) {
...
// 방법 3 : 초기화식, 증감식이 둘 이상인 경우
for (int i=0, j=100; i<=50 && j>=50; i++, j--) {
...
}
/* 실행결과
1
2
3
4
5
6
7
8
9
10 */
반복 횟수 알고 있을 때 주로 사용
100번 반복 같은 실행문을 단 몇줄로 줄여줌
public static void main(String[] args) {
int sum = 0; // sum 을 선언
for (int i=1; i<=100; i++) {
sum += i;
}
System.out.println("1~100 합 : " + sum);
}
/* 실행결과
1~100 합 : 5050 */
public static void main(String[] args) {
int sum = 0; // sum 을 선언
int i = 0; // i 를 선언
// i를 선언하지 않고, i=1로 값만 준다.
for (i=1; i<=100; i++) {
sum += i;
}
// for문은 돌다가 101에 빠져나오게 되고, 100까지의 합을 위해서 i-1 이 필요
System.out.println("1~" + (i-1) + " 합 : " + sum);
}
/* 실행결과
1~100 합 : 5050 */
public static void main(String[] args) {
int sum = 0;
for (int i=1; i<=100; i++) {
if (i % 3 == 0) {
sum += i;
}
}
System.out.println("3의 배수의 합 : " + sum);
}
public static void main(String[] args) {
for (float x=0.1f; x<=1.0f; x+=0.1f) {
System.out.println(x);
}
}
/* 실행결과
0.1
0.2
0.3
0.4
0.5
0.6
0.70000005
0.8000001
0.9000001 */
public static void main(String[] args) {
for(int i=1; i<=10; i++) {
if(i%2 != 0) { // 2로 나눈 나머지가 0이 아닌 경우(= 홀수인 경우) → i가 10일 때까지 반복
continue;
}
System.out.println(i); // 홀수가 아닌 경우 (= 짝수인 경우)
}
}
잘못된 사용
public void example(List<Integer> numbers) {
for (int i = 0; i < numbers.size(); i++) {
...
}
}
매번 i 를 numbers 의 크기만큼 반복할 때마다, numbers.size() 메서드를 호출하게 된다.
→ numbers의 size가 매우 클 경우, 그만큼의 불필요한 size() 메소드의 호출을 하게 되어버린다.
단, for 문의 반복 횟수가 예상가능하거나, numbers 의 길이가 크지 않은 경우에는 사용해도 무방하다.
size()
Collection 프레임워크 타입의 길이를 알고자 할 때 사용
올바른 사용
public void example(List<Integer> numbers) {
int numbersSize = numbers.size();
for (int i = 0; i < numbersSize; i++) {
...
}
}
for (타입 변수이름 : 배열 or 컬렉션) {
배열 or 컬렉션의 길이만큼 반복적으로 실행하고자 하는 문장;
}
class Control3_5 {
public static void main(String[] args) {
int[] arr = new int[]{1, 2, 3, 4, 5};
for (int e : arr) {
System.out.print(e + " ");
}
}
}
// 기존 코드 : for문
int arr[] = {1,2,3,4,5,6};
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
System.out.println("합계 : "+sum);
// 변경된 코드 : for-each문
int arr[] = {1,2,3,4,5,6};
int sum = 0;
for(int x : arr) { // for (변수 : 객체(배열))
sum += x;
}
System.out.println("합계 : "+sum);
public void example(List<Integer> numbers) {
for (int number : numbers) {
...
}
}
for문이 도는 동안, 배열(객체)에서 순서대로 하나씩 꺼내와서 사용하는 방식
for each는 객체에 크기만큼 반복 횟수를 정한다.
장점
별도의 형변환이나 get() 메서드를 호출할 필요 없이 순서에 따라서 해당 객체를 사용할 수 있다.
(for문에 비해) 사용하기 편하고 가독성도 좋다.
Index 관련 Exception들에 신경 쓰지 않아도 된다.
불필요한 반복에 신경 쓰지 않아도 된다.
단점
for (초기화; 조건식1; 증감식) {
조건식1의 결과가 참인 동안 반복적으로 실행하고자 하는 문장;
for (초기화; 조건식2; 증감식) {
조건식2의 결과가 참인 동안 반복적으로 실행하고자 하는 문장;
}
}
public static void main(String[] args) {
for (int m=2; m<=9; m++) {
System.out.println("*** " + m + "단 ***");
for (int n=1; n<=9; n++) {
System.out.println(m " x " + n + " = " + (m*n));
}
}
/* 실행결과 : 2 x n 지정횟수만큼 실행
*** 2단 ***
2 x 1 = 2
.
.
2 x 9 = 18
.
. */
public static void main(String[] args) {
for (int x=1; x<=10; x++) {
for (int y=1; y<=10; y++) {
if ((4*x + 5*y) == 60) {
System.out.println("(" + x + "," + y + ")");
}
}
}
}
// 방법 1
public static void main(String[] args) {
for (int i = 1; i < 5; i++) { // i 는 1, 2, 3, 4
for (int j = 1; j <= i; j++) { // j 는 1, 2, 3, 4
System.out.print("*");
if (i == j) {
System.out.println();
}
}
}
}
// 방법 2
public static void main(String[] args) {
for (int i = 1; i < 5; i++) { // i 는 1, 2, 3, 4
for (int j = 1; j <= i; j++) { // j 는 1, 2, 3, 4
System.out.print("*");
}
System.out.println();
}
}
/* 실행결과
*
**
***
**** */
/*
i가 1일 때, j는 1
i가 2일 때, j는 1, 2
i가 3일 때, j는 1, 2, 3
i가 4일 때, j는 1, 2, 3, 4
*/
public static void main(String[] args) {
for (int i = 1; i < 5; i++) { // i는 1, 2, 3, 4, 5
for (int j = 4; j > 0; j--) { // j는 4, 3, 2, 1
if (i < j) {
System.out.print(" ");
} else { // i >= j 인 경우
System.out.print("*");
}
}
System.out.println();
}
/* 실행결과
*
**
***
****
*/
/*
i가 1일 때, j는 공백(4) 공백(3) 공백(2) *(1)
i가 2일 때, j는 공백(4) 공백(3) *(2) *(1)
i가 3일 때, j는 공백(4) *(3) *(2) *(1)
i가 4일 때, j는 *(4) *(3) *(2) *(1)
*/
for (...) { // 종료 X
for(...) { // 종료 O
break;
}
}
Label: for (...) { // 종료 O
for(...) { // 종료 O
break Label;
// Label 이라는 이름이 붙은 for문을 종료 (즉, 바깥 for문을 종료하게 되는데, 이는 안쪽 for문도 함께 종료되는 것과 같다.)
}
}
무한반복문 or 복잡한 중첩반복문이 등장했을 때, 쉽게 벗어날 수 있는 방법
일반적인 break; 을 실행할 경우 : 단지 안쪽 for문 만 종료되고 바깥 for문에는 영향이 없다.
이름붙은 break; 을 실행할 경우 : 이름이 붙은 해당 for문을 종료하게 된다.
while (조건식) {
조건식의 결과가 참인 동안 반복적으로 실행하고자 하는 문장;
}
public static void main(String[] args) {
int i = 1;
while (i<=10) {
System.out.println(i);
i++;
}
}
/* 실행결과
1
2
3
4
5
6
7
8
9
10 */
조건식이 true일 경우, 반복 실행
조건식이 false가 될 경우, while 문 종료
주의!
while문은 잘못 사용할 경우, 무한 루프에 빠질 위험이 있다.
따라서, for문 사용을 권장한다.
public static void main(String[] args) {
int sum = 0;
int i = 0;
while(i<=100) {
sum += i;
i++;
}
System.out.println("1~" + (i-1) + " 합 : " + sum);
}
public static void main(String[] args) {
int i = 1;
while (true) {
int num = (int) (Math.random() * 6) + 1;
System.out.println(num);
if(num == 6) { // num 이 6이 나오면, while 문 종료
break; // break로 while 문 종료
}
}
System.out.println("프로그램 종료");
}
/* 실행결과
1
5
6
프로그램 종료 */
Q. while문과 Math.random() 메소드를 이용해서 2개의 주사위를 던졌을 때 나오는 눈을 (눈1, 눈2) 형태로 출력하고, 눈의 합이 5가 아니면 계속 주사위를 던지고, 눈의 합이 5이면 실행을 멈추는 코드를 작성해보세요.
눈의 합이 5가 되는 조합은 (1,4), (4,1), (2,3), (3,2)입니다.
public class Dice {
public static void main(String[] args) {
// while 문의 무한 반복을 위해 조건식에 true 를 사용
while(true) {
int num1 = (int) (Math.random() * 6) + 1;
int num2 = (int) (Math.random() * 6) + 1;
System.out.println("(" + num1 + "," + num2 + ")");
if ((num1 + num2) == 5) {
break;
}
}
}
}
A.
Math.random() 메소드는 0.0 <= Math.random() < 1.0 값을 가지는 임의의 double 타입의 데이터를 출력하는 메소드이다.
따라서, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 의 값을 가질 수 있다.
그러나 주사위 눈의 숫자는 1~6까지의 정수다.
즉, Math.random()가 가지는 소수를 주사위 눈이 가지는 숫자(1~6의 정수)로 만들어주는 것이 이 문제의 핵심이라는 것이다.
먼저, Math.random()가 가지는 소수를 주사위의 값과 비슷하게 만들어준다.
Math.random() * 6 은 0.0, 0.6, 1.2, 1.8, 2.4, 3.0, 3.6, 4.2, 4.8, 5.4 의 값을 가진다.
이를 int 타입으로 바꾸면 0, 0, 1, 1, 2, 3, 3, 4, 4, 5 의 값을 가지게 되는데, 당연히 0은 주사위 눈에 포함되지 않으므로 +1를 해준다.
결과적으로 1, 1, 2, 2, 3, 4, 4, 5, 5, 6 이 나오게 된다.
마지막으로 if문을 이용하여 주사위의 두 눈의 합이 5가 되는 조건식을 세운다.
Q. Math.random() * 7 이 안되는 이유?
Math.random() * 7 은 0.0, 0.7, 1.4, 2.1, 2.8, 3.5, 4.2, 4.9, 5.6, 6.3 의 값을 가진다.
이를 int 타입으로 바꾸면 0, 0, 1, 2, 2, 3, 4, 4, 5, 6 의 값을 가지게 되는데
주사위 눈 1~6으로 만들어주기 위해 +1를 하면 7를 가지게 되어 불가능하고,
+1을 하지 않으려 하기에는 0이라는 정수를 주사위가 포함할 수 없다.
int T = 3;
int cnt = 10;
while(T-- > 0) {
System.out.println(cnt--+" 루프 : "+T);
}
/* 출력 결과 -> T 변수의 값이 3이므로, 3번 돌고 끝난다.
10 루프 : 2
9 루프 : 1
8 루프 : 0
*/
do {
조건식의 결과가 참인 동안 반복적으로 실행하고자 하는 문장;
} while (조건식);
순서
do 를 거치고,
while(); 에서 ;를 붙여줘야 한다
public class t {
public static void main(String[] args) {
int num = 6; // 1. num 변수에 6을 할당
do {
System.out.println(num); // 2. num 변수 6이 출력
num++; // 3. 값이 1 증가
}
while (num <= 5); // 4. while의 조건식은 false → do while 반복문이 종료됨
System.out.println("program and.... "); // 5. "program and...." 가 출력됨
}
}
while : 조건식을 먼저 검사,
do - while : 조건식을 나중에 검사
while(조건식); 에는 세미콜론(;)을 붙여야 한다.
do - while 반복문은 무조건 한 번 이상 실행된다.
public class t {
public static void main(String[] args) {
int num = 4; // 1. num 변수에 4를 할당
do {
System.out.println(num); // 2. num 변수 4가 출력 // 5. num 변수 5가 출력
num++; // 3. 값이 1 증가 // 6. 값이 1 증가 합니다.
} while (num <= 5); // 4. while의 조건식은 true → do 코드로 다시 진입 // 7. while의 조건식이 false → do while 반복문이 종료됨
System.out.println("program and.... "); // 8. "program and...." 가 출력됨
}
}
class Control6_1 {
public static void main(String[] args) {
int sum = 0;
int i = 0;
while (true) {
if(sum > 100)
break;
++i;
sum += i;
}
System.out.println("i = " + i);
System.out.println("sum = " + sum);
}
}
class Control6_2 {
public static void main(String[] args) {
for (int i = 0; i <= 10; i++) {
// 3의 배수는 건너뜀 : 3, 6, 9
if (i % 3 == 0)
continue;
System.out.println("i = " + i);
}
}
}
/* 출력 결과
i = 1
i = 2
i = 4
i = 5
i = 7
i = 8
i = 10
*/
하위 로직을 수행하지 않고 다음 반복문으로 넘어간다
전체 반복 중에서 특정 조건에서만 반복을 건너뛸 때(제외할 때) 유용
참고: [JAVA] 중첩반복문 이름붙여서 벗어나기
참고: 자바 반복문 알고 쓰자!
참고: [JAVA] 자바 do while 반복문
참고: [Java] while(variable-- > 0) 개념 및 문법 정리