45. 스트림은 주의해서 사용하라
📌 스트림은 강력한 도구이지만, 상황에 맞게 신중하게 선택해서 사용해야 합니다.
📝 전체 내용 간단 요약
자바 8에서 도입된 스트림(Stream) 은 데이터 처리 코드를 간결하고 명확하게 표현할 수 있게 해줍니다. 하지만 모든 상황에서 스트림을 사용하는 것이 최선은 아니며, 반복문이 더 효과적인 경우도 많습니다. 따라서 상황에 맞춰 스트림과 반복문을 적절히 조합하여 사용하는 것이 중요합니다.
📚 미리 알아야 할 개념
스트림(Stream) 데이터 흐름을 나타내며, 컬렉션이나 배열의 데이터를 함수형 프로그래밍 방식으로 처리할 수 있도록 도와줍니다.
람다(Lambda) 이름 없는 작은 함수로, 스트림에서 간결한 데이터 처리를 가능하게 합니다.
반복문(Loop)
for
,while
등으로 데이터를 명령형으로 반복하여 처리하는 방식입니다.
🚨 주의사항
가독성 저하 주의 스트림을 남용하면 코드가 복잡해지고 이해하기 어려워질 수 있습니다. 매개변수 이름을 명확히 하고, 도우미 메서드를 적극 활용하세요.
char
타입 주의char
값을 처리할 때는 스트림보다 반복문이 더 직관적이고 명확합니다.무조건적 리팩터링 지양 기존 코드를 스트림으로 바꿀 때는 새로운 코드가 명확히 더 좋을 때만 변경하세요.
🔑 중요한 점
스트림이 적합한 경우 데이터 필터링, 변환, 집계와 같은 작업에 효과적입니다.
반복문이 적합한 경우 상태를 변경하거나 인덱스가 필요한 복잡한 로직에 적합합니다.
혼합 사용 권장 스트림과 반복문을 적절히 혼합해 사용하면 각 도구의 장점을 살릴 수 있습니다.
가독성을 위한 도우미 메서드 활용 스트림 코드를 짧고 명확하게 유지하기 위해 복잡한 로직을 별도 메서드로 분리하세요.
❌ 잘못된 예제 (가독성 저하)
List<String> names = List.of("Alice", "Bob", "Charlie", "David");
// 복잡한 스트림 파이프라인 (한 줄에 많은 작업을 처리함)
String result = names.stream()
.filter(name -> name.length() >= 5)
.map(String::toUpperCase)
.reduce((a, b) -> a + "," + b)
.orElse("");
System.out.println(result); // ALICE,CHARLIE,DAVID
⚠️ 문제점: 단계가 길어 가독성이 떨어지고, 나중에 유지보수하기 어렵습니다.
✅ 좋은 예제 (가독성 개선)
스트림으로 간결히 표현한 예
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);
// 짝수만 선택하여 제곱한 리스트로 만들기
List<Integer> squaresOfEvenNumbers = numbers.stream()
.filter(num -> num % 2 == 0)
.map(num -> num * num)
.collect(Collectors.toList());
System.out.println(squaresOfEvenNumbers); // [4, 16, 36]
반복문이 더 적합한 예 (char 처리)
String str = "Effective Java 3rd Edition";
int digitCount = 0;
// 반복문이 더 직관적
for (char c : str.toCharArray()) {
if (Character.isDigit(c)) {
digitCount++;
}
}
System.out.println("숫자의 개수: " + digitCount);
스트림과 반복문의 혼합 예시
List<List<String>> fruits = List.of(
List.of("apple", "banana"),
List.of("cherry", "date")
);
// 전체 리스트로 합치기
List<String> allFruits = new ArrayList<>();
for (List<String> list : fruits) {
list.stream().forEach(allFruits::add);
}
System.out.println(allFruits); // [apple, banana, cherry, date]
🚧 어려운 점
함수형 프로그래밍 사고방식: 명령형에 익숙한 경우 함수형 개념(지연 평가, 순수 함수)이 처음에는 어렵게 느껴질 수 있습니다.
지연 평가(Lazy Evaluation): 스트림 중간 연산은 실제 연산이 필요할 때만 실행된다는 점을 이해해야 합니다.
람다 표현식의 활용: 스트림 API를 효과적으로 사용하려면 람다 표현식에 익숙해져야 합니다.
💬 느낀점
스트림 API는 매우 강력하고 간결한 도구지만, 항상 스트림만 고집하는 것이 좋지 않다는 점을 배웠습니다. 각 상황에 가장 적합한 방법을 선택하는 능력을 키우고, 가독성 있는 코드를 작성하기 위해 노력해야겠다고 생각했습니다.
Last updated