개발일지

Java Stream API 마스터하기: 함수형 프로그래밍의 강력함 🌊

2024. 12. 10. 23:48
목차
  1. 1. Stream API 기초 개념 📚
  2. 2. Stream 연산의 종류 🔄
  3. 2.1 중간 연산 (Intermediate Operations)
  4. 2.2 최종 연산 (Terminal Operations)
  5. 3. 실전 활용 예제 💡
  6. 3.1 객체 스트림 처리
  7. 3.2 그룹화와 집계
  8. 4. 병렬 스트림 (Parallel Streams) ⚡
  9. 5. Stream API 성능 최적화 팁 🚀
  10. 5.1 적절한 스트림 선택
  11. 5.2 Short-circuiting 활용
  12. 결론 📝
  13. 실무 적용 시 고려사항 ⚠️

Java 8에서 도입된 Stream API는 컬렉션 데이터를 함수형 프로그래밍 방식으로 처리할 수 있게 해주는 강력한 도구입니다. 이번 글에서는 Stream API의 핵심 개념부터 실전 활용까지 상세히 알아보겠습니다.

1. Stream API 기초 개념 📚

Stream은 데이터의 흐름을 표현하는 객체로, 컬렉션의 요소들을 람다식을 이용해 효과적으로 처리할 수 있게 해줍니다.

List<String> names = Arrays.asList("John", "Jane", "Kim", "Park", "Lee");

// 기존 방식
List<String> filteredNames = new ArrayList<>();
for (String name : names) {
    if (name.length() <= 3) {
        filteredNames.add(name.toUpperCase());
    }
}

// Stream API 활용
List<String> streamFilteredNames = names.stream()
    .filter(name -> name.length() <= 3)
    .map(String::toUpperCase)
    .collect(Collectors.toList());

2. Stream 연산의 종류 🔄

2.1 중간 연산 (Intermediate Operations)

public class StreamIntermediateDemo {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        numbers.stream()
            .filter(n -> n % 2 == 0)    // 짝수 필터링
            .map(n -> n * 2)            // 값 변환
            .sorted()                    // 정렬
            .distinct()                  // 중복 제거
            .peek(System.out::println)   // 중간 결과 확인
            .collect(Collectors.toList());
    }
}

2.2 최종 연산 (Terminal Operations)

public class StreamTerminalDemo {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        // 다양한 최종 연산 예시
        long count = numbers.stream().count();
        Optional<Integer> max = numbers.stream().max(Integer::compareTo);
        boolean allMatch = numbers.stream().allMatch(n -> n > 0);
        boolean anyMatch = numbers.stream().anyMatch(n -> n % 2 == 0);
        Optional<Integer> find = numbers.stream().findFirst();

        // collect 연산
        List<Integer> collected = numbers.stream()
            .collect(Collectors.toList());
    }
}

3. 실전 활용 예제 💡

3.1 객체 스트림 처리

public class Person {
    private String name;
    private int age;
    private String city;

    // 생성자, getter, setter 생략
}

public class PersonStreamExample {
    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
            new Person("John", 25, "New York"),
            new Person("Jane", 30, "London"),
            new Person("Kim", 35, "Seoul")
        );

        // 나이가 30 이상인 사람들의 이름을 알파벳 순으로 정렬
        List<String> filteredNames = people.stream()
            .filter(p -> p.getAge() >= 30)
            .map(Person::getName)
            .sorted()
            .collect(Collectors.toList());
    }
}

3.2 그룹화와 집계

public class StreamGroupingExample {
    public static void main(String[] args) {
        List<Person> people = getPeople(); // 사람 목록 가져오기

        // 도시별 평균 나이 계산
        Map<String, Double> avgAgeByCity = people.stream()
            .collect(Collectors.groupingBy(
                Person::getCity,
                Collectors.averagingInt(Person::getAge)
            ));

        // 도시별 인원 수 계산
        Map<String, Long> countByCity = people.stream()
            .collect(Collectors.groupingBy(
                Person::getCity,
                Collectors.counting()
            ));
    }
}

4. 병렬 스트림 (Parallel Streams) ⚡

public class ParallelStreamDemo {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // 순차 스트림
        long startTime = System.nanoTime();
        numbers.stream()
            .map(n -> performHeavyComputation(n))
            .collect(Collectors.toList());
        long endTime = System.nanoTime();

        // 병렬 스트림
        long parallelStartTime = System.nanoTime();
        numbers.parallelStream()
            .map(n -> performHeavyComputation(n))
            .collect(Collectors.toList());
        long parallelEndTime = System.nanoTime();

        // 성능 비교 출력
        System.out.println("순차 처리 시간: " + (endTime - startTime));
        System.out.println("병렬 처리 시간: " + (parallelEndTime - parallelStartTime));
    }
}

5. Stream API 성능 최적화 팁 🚀

5.1 적절한 스트림 선택

public class StreamOptimizationTips {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        // 작은 데이터셋: 순차 스트림 사용
        numbers.stream()
            .filter(n -> n % 2 == 0)
            .collect(Collectors.toList());

        // 큰 데이터셋: 병렬 스트림 고려
        numbers.parallelStream()
            .filter(n -> n % 2 == 0)
            .collect(Collectors.toList());
    }
}

5.2 Short-circuiting 활용

public class ShortCircuitExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // findFirst()를 사용한 조기 종료
        Optional<Integer> firstEven = numbers.stream()
            .filter(n -> n % 2 == 0)
            .findFirst();

        // anyMatch()를 사용한 조기 종료
        boolean hasEven = numbers.stream()
            .anyMatch(n -> n % 2 == 0);
    }
}

결론 📝

Stream API는 Java에서 데이터 처리를 위한 강력하고 유연한 도구입니다. 주요 이점은:

  • 간결하고 가독성 높은 코드 작성 가능
  • 함수형 프로그래밍 스타일 지원
  • 병렬 처리를 통한 성능 최적화
  • 풍부한 중간/최종 연산 제공

실무 적용 시 고려사항 ⚠️

  • 상황에 따른 적절한 스트림 선택 (순차/병렬)
  • 성능에 민감한 경우 벤치마킹 필수
  • 가독성과 유지보수성 고려
  • Short-circuiting 연산 활용

Stream API를 효과적으로 활용하면 더 깔끔하고 효율적인 코드를 작성할 수 있습니다. 실제 프로젝트에서 적절히 활용하여 코드 품질을 향상시키시기 바랍니다.

저작자표시 비영리 변경금지 (새창열림)

'개발일지' 카테고리의 다른 글

Java Records: 현대적 데이터 클래스의 새로운 패러다임 📝  (0) 2024.12.10
Java Optional: 우아한 null 처리의 완벽 가이드 ✨  (0) 2024.12.10
Java String Pool의 내부 동작 원리: 메모리 최적화와 문자열 관리 심층 분석 📘  (0) 2024.12.10
JavaScript Set과 Map: 데이터를 효율적으로 다루는 방법  (0) 2024.12.02
자바스크립트 함수 완벽 가이드: 함수 표현식부터 모던 자바스크립트까지  (0) 2024.11.30
  1. 1. Stream API 기초 개념 📚
  2. 2. Stream 연산의 종류 🔄
  3. 2.1 중간 연산 (Intermediate Operations)
  4. 2.2 최종 연산 (Terminal Operations)
  5. 3. 실전 활용 예제 💡
  6. 3.1 객체 스트림 처리
  7. 3.2 그룹화와 집계
  8. 4. 병렬 스트림 (Parallel Streams) ⚡
  9. 5. Stream API 성능 최적화 팁 🚀
  10. 5.1 적절한 스트림 선택
  11. 5.2 Short-circuiting 활용
  12. 결론 📝
  13. 실무 적용 시 고려사항 ⚠️
'개발일지' 카테고리의 다른 글
  • Java Records: 현대적 데이터 클래스의 새로운 패러다임 📝
  • Java Optional: 우아한 null 처리의 완벽 가이드 ✨
  • Java String Pool의 내부 동작 원리: 메모리 최적화와 문자열 관리 심층 분석 📘
  • JavaScript Set과 Map: 데이터를 효율적으로 다루는 방법
벤지_
벤지_
디자인 전공의 비전공자에서 개발자로 거듭나는 이야기를 담고자 합니다.
벤지_
벤지의 개발일지
벤지_
전체
오늘
어제
  • 분류 전체보기 (42)
    • 개발일지 (42)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 자바스크립트
  • SpringRESTDocs
  • 프론트엔드
  • JPA
  • Set
  • 화살표 함수
  • 투두리스트
  • KPT회고
  • 배포
  • 코드스테이츠
  • 리액트
  • JavaScript
  • JUnit
  • 리플렉션 api
  • 부트캠프
  • AWS
  • til
  • SQL
  • map
  • java
  • 개발일지
  • 데이터베이스
  • 백엔드
  • 스프링
  • Spring
  • 자바
  • React
  • 프리프로젝트
  • 테스트
  • 국비지원

최근 댓글

최근 글

hELLO · Designed By 정상우.
벤지_
Java Stream API 마스터하기: 함수형 프로그래밍의 강력함 🌊
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.