Header Ads Widget

Responsive Advertisement

[Java] 3장. 스트림(Stream) 고급 중간 연산 정리

3장. 스트림(Stream) 고급 중간 연산 정리

📚 3장. 스트림(Stream) 고급 중간 연산 정리

🎯 설명으로 이해하는 스트림 고급 중간 연산

스트림에서 자주 사용하는 중간 연산 중 고급 개념 13가지를 정리합니다.

1. map()

설명: 각 요소를 지정된 함수로 변환하여 새로운 스트림을 생성합니다.

용도: 값을 가공하거나 속성만 추출할 때 유용합니다.

List<String> list = Arrays.asList("a", "b", "c");
list.stream()
    .map(s -> s.toUpperCase())
    .forEach(System.out::println);

실행 결과:

A
B
C

코드 분석:

  • map(): 각 요소를 대문자로 변환
  • forEach(): 변환된 결과를 출력

2. flatMap()

설명: 각 요소를 여러 요소로 바꾸고, 이들을 하나의 스트림으로 평탄화(flatten)합니다.

용도: 리스트 안의 리스트처럼 중첩된 구조를 펼칠 때 사용합니다.

List<List<String>> list = Arrays.asList(
    Arrays.asList("a", "b"),
    Arrays.asList("c", "d")
);
list.stream()
    .flatMap(Collection::stream)
    .forEach(System.out::println);

실행 결과:

a
b
c
d

코드 분석:

  • flatMap(Collection::stream): 리스트 내부 리스트들을 하나의 스트림으로 병합
  • forEach(): 병합된 스트림을 출력

추가 설명: map()과 달리 flatMap()은 다수의 스트림을 병합하는 역할을 함

3. peek()

설명: 중간 연산 과정 중 각 요소를 살펴볼 수 있게 도와주는 디버깅 용 메서드입니다.

용도: 스트림 처리 과정 중간의 상태를 확인할 때 사용합니다.

List<String> list = Arrays.asList("apple", "banana", "cherry");
list.stream()
    .peek(s -> System.out.println("Before: " + s))
    .map(String::toUpperCase)
    .peek(s -> System.out.println("After: " + s))
    .collect(Collectors.toList());

실행 결과:

Before: apple
After: APPLE
Before: banana
After: BANANA
Before: cherry
After: CHERRY

코드 분석:

  • peek(): 중간 흐름을 로그처럼 확인 (변환 전과 후)
  • map(): 대문자로 변환
  • collect(): 최종 리스트로 수집

추가 설명: peek()디버깅 목적이기 때문에 실제 로직에 영향은 없음

4. filter()

설명: 주어진 조건에 해당하는 요소만 통과시킵니다.

용도: 특정 조건에 맞는 데이터만 추출할 때 사용합니다.

List<String> fruits = Arrays.asList("apple", "banana", "blueberry", "cherry");
fruits.stream()
    .filter(fruit -> fruit.startsWith("b"))
    .forEach(System.out::println);

실행 결과:

banana
blueberry

코드 분석:

  • filter(): 'b'로 시작하는 문자열만 통과
  • forEach(): 통과한 항목 출력

추가 설명: 조건은 fruit -> fruit.startsWith("b") 와 같이 람다식으로 자유롭게 지정 가능

5. distinct()

설명: 중복된 요소를 제거하고 유일한 값만 남깁니다.

용도: 중복된 데이터를 제거하고 싶을 때 사용합니다.

List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 3);
numbers.stream()
    .distinct()
    .forEach(System.out::println);

실행 결과:

1
2
3

코드 분석:

  • distinct(): 중복 제거
  • forEach(): 고유 값 출력

6. sorted()

설명: 요소를 기본 또는 사용자 정의 기준에 따라 정렬합니다.

용도: 정렬된 데이터가 필요한 경우 사용합니다.

List<String> words = Arrays.asList("banana", "apple", "cherry");
words.stream()
    .sorted()
    .forEach(System.out::println);

실행 결과:

apple
banana
cherry

코드 분석:

  • sorted(): 알파벳 오름차순 정렬
  • forEach(): 정렬 결과 출력

7. limit(n)

설명: 스트림에서 앞에서 n개만 남기고 나머지는 제거합니다.

용도: 페이징 처리나 일부만 미리보기 출력할 때 사용합니다.

List<Integer> numbers = Arrays.asList(10, 20, 30, 40, 50);
numbers.stream()
    .limit(3)
    .forEach(System.out::println);

실행 결과:

10
20
30

코드 분석:

  • limit(3): 앞에서 3개의 요소만 남긴다
  • forEach(): 결과 출력

8. skip(n)

설명: 스트림에서 앞의 n개를 건너뛰고 나머지를 사용합니다.

용도: 페이징 처리 시 offset처럼 사용합니다.

List<Integer> numbers = Arrays.asList(10, 20, 30, 40, 50);
numbers.stream()
    .skip(2)
    .forEach(System.out::println);

실행 결과:

30
40
50

코드 분석:

  • skip(2): 앞의 2개 요소를 건너뛴다
  • forEach(): 나머지 출력

9. anyMatch()

설명: 하나라도 조건을 만족하는 요소가 있으면 true를 반환합니다.

용도: 조건에 맞는 요소가 존재하는지만 확인할 때 사용합니다.

List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
boolean hasEven = nums.stream()
    .anyMatch(n -> n % 2 == 0);
System.out.println(hasEven);

실행 결과:

true

코드 분석:

  • anyMatch(): 짝수가 하나라도 있으면 true 반환

10. allMatch()

설명: 모든 요소가 조건을 만족하면 true를 반환합니다.

용도: 전체 요소가 특정 조건을 만족하는지 검증할 때 사용합니다.

List<Integer> nums = Arrays.asList(2, 4, 6);
boolean allEven = nums.stream()
    .allMatch(n -> n % 2 == 0);
System.out.println(allEven);

실행 결과:

true

코드 분석:

  • allMatch(): 모든 수가 짝수라면 true 반환

11. noneMatch()

설명: 조건을 만족하는 요소가 하나도 없으면 true를 반환합니다.

용도: 특정 조건을 아예 만족하지 않는지 확인할 때 사용합니다.

List<Integer> nums = Arrays.asList(1, 3, 5);
boolean noEven = nums.stream()
    .noneMatch(n -> n % 2 == 0);
System.out.println(noEven);

실행 결과:

true

코드 분석:

  • noneMatch(): 짝수가 하나도 없으므로 true 반환

12. findFirst()

설명: 스트림에서 첫 번째 요소를 Optional로 반환합니다.

용도: 가장 앞에 있는 값을 꺼낼 때 사용합니다.

Optional<String> first = Stream.of("a", "b", "c")
    .findFirst();
first.ifPresent(System.out::println);

실행 결과:

a

코드 분석:

  • findFirst(): 첫 번째 요소를 Optional로 감싸서 반환
  • ifPresent(): 값이 있으면 출력

13. reduce()

설명: 스트림의 요소를 하나로 축소(집계)합니다. 합계, 곱셈, 최대값 등에 활용됩니다.

용도: 모든 요소를 누적 처리하여 단일 값을 만들고 싶을 때 사용합니다.

int sum = Stream.of(1, 2, 3, 4)
    .reduce(0, Integer::sum);
System.out.println(sum);

실행 결과:

10

코드 분석:

  • reduce(): 누산기(accumulator)를 통해 전체 합계 계산





댓글 쓰기

0 댓글