스택큐힙리스트

자바 스프링 개발 시작하기 - 5일차 모던 Java 스킬업 본문

개발

자바 스프링 개발 시작하기 - 5일차 모던 Java 스킬업

스택큐힙리스트 2025. 7. 11. 12:13
반응형

1. 오늘의 목표

람다‧Stream‧Record‧Optional 네 가지 키워드를 활용해 실시간 로그를 필터링하고 집계하는 예제를 만들며 “함수형 사고”에 감 잡기. 프로젝트 전반에서 반복될 깨끗한 데이터 파이프라인을 설계할 토대를 다집니다.


2. 왜 배워야 할까?

  • 람다식으로 익명 클래스를 걷어내 코드량 ↓, 가독성 ↑.
  • Stream API로 멀티스레드 컬렉션 처리까지 한 줄에.
  • Record로 DTO 보일러플레이트 제거, 불변 객체 기본화.
  • Optional로 NullPointerException 방지 & “null 체크” 관습 탈출.

3. 실습 – 실시간 로그 필터·집계 파이프라인

// Record: 로그 한 줄 정의
public record LogLine(long ts, String level, String msg) {}

// (1) 스트림 파이프라인 – 필터 → 매핑 → 집계
Map<String, Long> errorCounts =
    logStream()                       // 실시간 스트림(예: KafkaConsumer records)
        .map(LogParser::toLogLine)    // 문자열 → LogLine(Record)
        .filter(l -> l.level().equals("ERROR"))
        .collect(Collectors.groupingBy(
            LogLine::msg, Collectors.counting()));

// (2) Optional 활용 – 가장 흔한 에러 메시지 출력
errorCounts.entrySet().stream()
    .max(Map.Entry.comparingByValue())
    .map(Map.Entry::getKey)
    .ifPresentOrElse(
        m -> System.out.println("TOP ERROR ▶ " + m),
        () -> System.out.println("No errors 🎉"));

핵심 포인트

  1. filter()에 람다식 전달해 ERROR 레벨만 추출.
  2. groupingBy로 실시간 카운트; 필요하면 Collectors.toConcurrentMap으로 교체해 병렬 집계.
  3. Optional.ifPresentOrElse로 결과가 없을 때도 깔끔한 분기 처리.

4. 실전 적용 팁

  • Record vs Lombok
    Record는 JDK 14+ 정식 포함. @Getters나 @AllArgsConstructor 없이도 equals/hashCode 자동 제공 → 간결성 & 유지보수성 상승.
  • Stream 성능
    대량 데이터라면 parallel()을 고민하되 CPU 코어·스레드풀 상황을 먼저 체크. 무차별 parallel()은 오히려 병목.
  • Optional 남용 금지
    필드나 파라미터보단 리턴 타입 에만 사용 → 불필요한 객체 생성 방지.
  • 테스트 전략
    Stream 파이프라인은 단계별로 peek() 대신 JUnit5 매개변수 테스트를 활용하여 기대 출력값을 검증.

5. 마무리 & 내일 예고

오늘 배운 함수형 도구들은 앞으로 컨트롤러·서비스·레포지토리 층 어디서든 “한 줄 파이프라인”으로 재사용됩니다.

반응형
Comments