회원의 주문 내역에서 특정 금액 이상의 주문만 골라내려면 무엇이 필요할까? 주문 금액을 저장할 배열, 각 주문을 훑어볼 반복문, 조건에 따라 결과를 분리할 조건문이 필요하다. 세 가지를 따로 외우기보다 하나의 문제로 연결해 보자.
int payment = 28_000;
if (payment >= 50_000) {
System.out.println("무료 배송");
} else if (payment >= 30_000) {
System.out.println("배송비 할인");
} else {
System.out.println("기본 배송비");
}
조건은 위에서 아래로 평가하고, if 또는 else if에서 참이 되면 나머지 분기는 실행하지 않는다. if를 여러 번 독립적으로 작성하면 각각의 조건이 따로 평가된다는 차이가 있다.
간단한 두 선택지에는 삼항 연산자도 쓸 수 있다.
String label = payment >= 30_000 ? "혜택 대상" : "일반 주문";
복잡한 분기는 읽기 쉬운 if가 낫다.
switchint deliveryStatus = 2;
switch (deliveryStatus) {
case 1:
System.out.println("결제 완료");
break;
case 2:
System.out.println("배송 준비");
break;
case 3:
System.out.println("배송 중");
break;
default:
System.out.println("알 수 없는 상태");
}
기존 switch 문에서는 break를 빼면 다음 case로 계속 진행할 수 있으므로 주의해야 한다. 최근 Java에서는 ->를 사용하는 switch 표현식도 지원한다.
String status = switch (deliveryStatus) {
case 1 -> "결제 완료";
case 2 -> "배송 준비";
case 3 -> "배송 중";
default -> "알 수 없음";
};
forfor (int attempt = 1; attempt <= 3; attempt++) {
System.out.println("요청 " + attempt + "회차");
}
for (초기식; 조건식; 증감식)은 초기식 실행 → 조건 확인 → 본문 실행 → 증감식 실행을 반복한다.
반면 반복을 끝낼 조건이 상황에 따라 달라지면 while이 자연스럽다.
int retry = 0;
while (retry < 3) {
retry++;
}
do-while은 본문을 먼저 실행한 뒤 조건을 확인하므로 적어도 한 번은 실행된다.
int inputCount = 0;
do {
inputCount++;
} while (inputCount < 1);
int[] payments = {12_000, 53_000, 37_000, 81_000};
System.out.println(payments[0]); // 12000
System.out.println(payments.length); // 4
배열은 같은 타입의 데이터를 여러 개 담는다. 인덱스는 0부터 시작하고, 마지막 인덱스는 length - 1이다. 배열의 크기는 생성한 뒤 변경할 수 없다.
public class OrderFilter {
public static void main(String[] args) {
int[] payments = {12_000, 53_000, 37_000, 81_000};
int qualifyingCount = 0;
for (int payment : payments) {
if (payment >= 50_000) {
qualifyingCount++;
System.out.println("혜택 대상: " + payment + "원");
}
}
System.out.println("총 " + qualifyingCount + "건");
}
}
실행 결과:
혜택 대상: 53000원
혜택 대상: 81000원
총 2건
for (int payment : payments)는 향상된 for문(for-each)이다. 배열의 각 원소를 차례로 꺼낼 때 적합하다. 인덱스가 필요하거나 요소를 특정 위치에서 수정해야 한다면 일반 for가 편하다.
break와 continuebreak: 가장 가까운 반복문을 즉시 끝낸다.continue: 현재 반복 회차의 남은 본문을 건너뛰고 다음 회차로 진행한다.int[] requestCodes = {200, 200, 429, 200};
for (int code : requestCodes) {
if (code == 429) {
System.out.println("요청 제한: 처리 중단");
break;
}
if (code != 200) {
continue;
}
System.out.println("정상 처리");
}
break는 switch 문에서도 사용하지만 continue는 반복문에서만 의미가 있다.
요일별 방문자 수처럼 행과 열이 있는 데이터는 다음처럼 표현할 수 있다.
int[][] visits = {
{12, 15, 11},
{21, 18, 25}
};
for (int day = 0; day < visits.length; day++) {
int dayTotal = 0;
for (int hour = 0; hour < visits[day].length; hour++) {
dayTotal += visits[day][hour];
}
System.out.println(day + "일 차 합계: " + dayTotal);
}
0일 차 합계: 38
1일 차 합계: 64
자바의 2차원 배열은 배열 안에 배열이 들어 있는 구조다. 각 행의 길이가 서로 다를 수 있으므로 내부 반복문의 조건에 visits[day].length를 사용한다.
int[] numbers = {10, 20, 30};
// System.out.println(numbers[3]); // ArrayIndexOutOfBoundsException
배열 길이가 3이면 유효한 인덱스는 0, 1, 2뿐이다. 반복문에서 < numbers.length를 <= numbers.length로 작성하는 실수가 흔하다.
또한 while에서는 카운터 변경을 빠뜨리면 무한 반복이 생길 수 있다. continue를 만나기 전에 증가시켜야 하는 값이 누락되지 않았는지도 확인하자.
if, else if, else는 조건의 우선순위를 표현한다.switch는 하나의 값을 여러 선택지와 비교할 때 유용하다.for는 횟수 중심, while은 조건 중심의 반복에 잘 어울린다.do-while은 한 번 실행한 뒤 조건을 확인한다.break는 반복 종료, continue는 다음 반복으로 이동한다.