조건문의 고급 활용
자바에서 조건문은 프로그램의 흐름을 제어하는 핵심 요소입니다.
기본적인 if-else 구문을 넘어 더 효율적인 방법들을 살펴보겠습니다.
조건문 유형 | 특징 | 적합한 상황 |
---|---|---|
if-else | 가장 기본적인 조건 분기 | 단순한 조건 검사 |
switch | 다중 조건 분기, Java 12+ 표현식 지원 | 동일 변수의 여러 값 비교 |
삼항 연산자 | 간결한 조건부 할당 | 단순한 조건부 값 할당 |
패턴 매칭 | Java 17+ 타입 패턴 매칭 | 객체 타입 검사와 캐스팅 |
Switch 표현식 (Java 12+)
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
|
// 전통적인 switch 문
switch (day) {
case MONDAY:
case FRIDAY:
case SUNDAY:
numLetters = 6;
break;
case TUESDAY:
numLetters = 7;
break;
case THURSDAY:
case SATURDAY:
numLetters = 8;
break;
case WEDNESDAY:
numLetters = 9;
break;
default:
throw new IllegalStateException(“Invalid day: “ + day);
}
// 현대적인 switch 표현식 (Java 12+)
numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY –> 6;
case TUESDAY –> 7;
case THURSDAY, SATURDAY –> 8;
case WEDNESDAY –> 9;
default –> throw new IllegalStateException(“Invalid day: “ + day);
};
|
cs |
패턴 매칭 (Java 17+)
1
2
3
4
5
6
7
8
9
10
11
|
// 전통적인 instanceof 사용
if (obj instanceof String) {
String s = (String) obj;
// s 사용
}
// 패턴 매칭 사용 (Java 17+)
if (obj instanceof String s) {
// s 바로 사용 가능
}
|
cs |
반복문의 고급 활용
자바에서 제공하는 다양한 반복문 구조와 그 최적화 방법을 살펴보겠습니다.
반복문 유형 | 특징 | 적합한 상황 |
---|---|---|
for | 초기화, 조건, 증감이 명확한 구조 | 정해진 횟수 반복 |
enhanced for | 컬렉션 순회에 최적화 | 배열/컬렉션 모든 요소 처리 |
while | 조건이 참인 동안 반복 | 조건에 따른 반복 |
do-while | 최소 한 번은 실행 보장 | 최소 한 번 실행 필요 시 |
Stream API | 함수형 프로그래밍 스타일 | 데이터 변환, 필터링, 집계 |
향상된 for문과 이터레이터
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
// 기본 for문
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 향상된 for문 (더 간결하고 오류 가능성 낮음)
for (String item : list) {
System.out.println(item);
}
// Iterator 사용 (컬렉션 순회 중 요소 제거 시 안전)
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if (item.isEmpty()) {
iterator.remove(); // ConcurrentModificationException 방지
}
}
|
cs |
Stream API 활용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
// 전통적인 방식
List<String> filtered = new ArrayList<>();
for (String s : strings) {
if (s.length() > 3) {
filtered.add(s.toUpperCase());
}
}
// Stream API 활용
List<String> filtered = strings.stream()
.filter(s –> s.length() > 3)
.map(String::toUpperCase)
.collect(Collectors.toList());
|
cs |
제어 흐름 최적화 기법
1. 루프 불변 코드 외부로 이동
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// 비효율적인 코드
for (int i = 0; i < list.size(); i++) {
// list.size()가 매 반복마다 호출됨
complex.calculate(Math.PI); // 상수 계산이 반복됨
}
// 최적화된 코드
int size = list.size(); // 한 번만 계산
double piValue = Math.PI; // 상수 미리 계산
for (int i = 0; i < size; i++) {
complex.calculate(piValue);
}
|
cs |
2. 조기 반환 및 실패 빠른 검사
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
// 중첩된 조건문
public void processData(Data data) {
if (data != null) {
if (data.isValid()) {
if (data.hasPermission()) {
// 실제 처리 로직
}
}
}
}
// 조기 반환으로 최적화
public void processData(Data data) {
if (data == null) return;
if (!data.isValid()) return;
if (!data.hasPermission()) return;
// 실제 처리 로직
}
|
cs |
3. 루프 융합
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
// 분리된 루프
for (int i = 0; i < n; i++) {
a[i] = b[i] * c[i];
}
for (int i = 0; i < n; i++) {
d[i] = a[i] * e[i];
}
// 융합된 루프
for (int i = 0; i < n; i++) {
a[i] = b[i] * c[i];
d[i] = a[i] * e[i];
}
|
cs |
실전 예제: 복잡한 데이터 처리
다음은 사용자 데이터를 필터링하고 변환하는 고급 예제입니다.
-
Stream API를 사용한 선언적 프로그래밍
-
메소드 참조를 통한 간결한 코드
-
체이닝을 통한 다단계 데이터 처리
-
비즈니스 로직 분리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public class UserProcessor {
public List<UserDTO> processActiveUsers(List<User> users) {
return users.stream()
.filter(User::isActive)
.filter(user –> user.getLoginCount() > 5)
.sorted(Comparator.comparing(User::getLastLoginDate).reversed())
.limit(10)
.map(this::convertToDTO)
.collect(Collectors.toList());
}
private UserDTO convertToDTO(User user) {
UserDTO dto = new UserDTO();
dto.setId(user.getId());
dto.setUsername(user.getUsername());
dto.setLastLoginDate(user.getLastLoginDate());
return dto;
}
}
|
cs |
자바의 제어문과 반복문을 효율적으로 활용하는 것은 성능 최적화와 코드 가독성 향상에 중요한 역할을 합니다. 현대적인 자바 기능을 활용하여 더 간결하고 유지보수가 용이한 코드를 작성할 수 있습니다.