자바 개발자라면 꿈 같은 Stream API 10가지 패턴

2025. 3. 31. 15:27IT정보/프로그래밍 가이드

Java 8부터 도입된 Stream API는 컬렉션(List, Map 등)을 더욱 간결하고 선언적으로 처리할 수 있게 도와주는 도구입니다. 반복문과 조건문으로 복잡하게 작성하던 로직들을 몇 줄로 처리할 수 있어 코드의 가독성과 유지보수성이 크게 향상되죠.

하지만 Stream API는 처음 접하면 다소 낯설고 어렵게 느껴질 수 있습니다. 특히 map(), filter(), flatMap() 같은 연산들이 익숙하지 않으면 오히려 코드가 더 헷갈릴 수도 있죠.

그래서 이 글에서는 현업에서 자주 쓰이는 10가지 Stream API 패턴직관적인 예제와 출력값과 함께 정리했습니다. 이 패턴들만 익혀도 대부분의 실무 Stream 코드는 자신 있게 작성할 수 있을 거예요.

 


✅ Java Stream API 자주 쓰는 패턴 10가지 (예제 + 출력 포함)

🔹 예시 데이터 (공통)

List<User> users = List.of(
    new User("Alice", "alice@example.com", 25, "Seoul", List.of("java", "spring")),
    new User("Bob", "bob@example.com", 17, "Busan", List.of("java", "react")),
    new User("Charlie", "charlie@example.com", 30, "Seoul", List.of("spring", "docker"))
);



1. filter + map: 조건 걸고 값 변환

List<String> adultNames = users.stream()
    .filter(user -> user.getAge() >= 20)
    .map(User::getName)
    .collect(Collectors.toList());
System.out.println(adultNames);

💡 출력:

[Alice, Charlie]



2. collect(Collectors.toList()): 리스트로 수집

List<String> emails = users.stream()
    .map(User::getEmail)
    .collect(Collectors.toList());
System.out.println(emails);

💡 출력:

[alice@example.com, bob@example.com, charlie@example.com]



3. map으로 객체 복사하거나 DTO 변환하기

List<UserDto> dtos = users.stream()
    .map(user -> new UserDto(user.getName(), user.getEmail()))
    .collect(Collectors.toList());
dtos.forEach(System.out::println);

💡 출력:

UserDto{name='Alice', email='alice@example.com'}
UserDto{name='Bob', email='bob@example.com'}
UserDto{name='Charlie', email='charlie@example.com'}



4. sorted(): 정렬하기

List<String> sortedNames = users.stream()
    .sorted(Comparator.comparing(User::getAge))
    .map(User::getName)
    .collect(Collectors.toList());
System.out.println(sortedNames);

💡 출력:

[Bob, Alice, Charlie]



5. distinct(): 중복 제거

List<String> cities = users.stream()
    .map(User::getCity)
    .distinct()
    .collect(Collectors.toList());
System.out.println(cities);

💡 출력:

[Seoul, Busan]

 


6. flatMap(): 리스트 안의 리스트 펼치기

List<String> allTags = users.stream()
    .flatMap(user -> user.getTags().stream())
    .distinct()
    .collect(Collectors.toList());
System.out.println(allTags);

💡 출력:

[java, spring, react, docker]



7. groupingBy(): 그룹화 하기

Map<String, List<User>> usersByCity = users.stream()
    .collect(Collectors.groupingBy(User::getCity));
System.out.println(usersByCity.keySet());

💡 출력:

[Seoul, Busan]



8. anyMatch / allMatch / noneMatch: 조건 매칭 여부

boolean hasAdult = users.stream()
    .anyMatch(user -> user.getAge() >= 20);
System.out.println(hasAdult);

💡 출력:

true



9. count(): 개수 세기

long adultCount = users.stream()
    .filter(user -> user.getAge() >= 20)
    .count();
System.out.println(adultCount);

💡 출력:

2



10. peek(): 디버깅 또는 중간 확인

List<String> names = users.stream()
    .peek(user -> System.out.println("사용자 확인: " + user.getName()))
    .map(User::getName)
    .collect(Collectors.toList());

💡 출력:

사용자 확인: Alice
사용자 확인: Bob
사용자 확인: Charlie

 

✅ 마무리: Stream, 익숙해지면 강력한 무기!

Stream API는 잘만 사용하면 자바 개발자의 생산성을 비약적으로 높여주는 도구입니다. 오늘 소개한 10가지 패턴은 실무에서 자주 등장하는 형태들이고, 그 흐름에 익숙해지면 복잡한 데이터를 처리하는 데에도 막힘이 없어질 거예요.

💡 익숙해지기 위한 팁

  • 기존 for문 코드를 Stream으로 바꿔보는 연습
  • 공식 문서나 Java API 문서 읽기
  • 동료의 Stream 코드 리뷰하며 패턴 익히기

앞으로도 다양한 예제와 함께 Stream 관련 내용을 블로그에 더 다룰 예정이니, 자주 놀러 오세요! 🙌