본문으로 건너뛰기
Advertisement

스트림의 중간 연산 (Intermediate Operations)

중간 연산은 스트림 파이프라인을 구성하며, 어떠한 가공 로직을 적용할지를 명시합니다. 중간 연산의 결과는 항상 스트림을 반환 하므로, 다른 중간 연산메서드들을 체이닝(Chaining)하여 여러 번 연결할 수 있습니다.

1. 필터링: filter, distinct

스트림에서 특정 조건에 맞는 요소만 추출하거나, 중복을 제거할 때 사용합니다.

  • filter(Predicate): 주어진 조건(람다식 표현으로 true를 반환하는 요소)에 맞는 요소만 고릅니다.
  • distinct(): 스트림의 중복된 요소를 제거합니다. (내부적으로 Object.equals() 사용)
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);

numbers.stream()
.distinct() // 중복 제거: 1, 2, 3, 4, 5
.filter(n -> n % 2 == 0) // 짝수 추출: 2, 4
.forEach(System.out::println);

2. 변환: map, flatMap

데이터의 형태를 원하는 형태로 변환할 때 매우 자주 사용됩니다.

  • map(Function): 스트림 내의 요소를 다른 값으로 치환하거나, 객체의 특정 필드만 뽑아낼 때 사용합니다.
  • flatMap(Function): 중첩 구조(예: 문자열 배열의 리스트)를 한 단계 평탄화(Flatten)하여 단일 스트림으로 만들 때 사용합니다.
List<String> words = Arrays.asList("apple", "banana", "cherry");

// 단어를 모두 대문자로 변환
words.stream()
.map(String::toUpperCase)
.forEach(System.out::println); // APPLE, BANANA, CHERRY
// flatMap 예제
List<List<String>> nestedList = Arrays.asList(
Arrays.asList("A", "B"),
Arrays.asList("C", "D")
);

// 단일 리스트 구조로 평탄화
nestedList.stream()
.flatMap(Collection::stream)
.forEach(System.out::print); // ABCD 출력

3. 정렬: sorted

요소들을 정렬합니다. 인자를 넘기지 않으면 기본 정렬 기준(Comparable)을 따르며, 사용자 정의 Comparator를 넘길 수도 있습니다.

List<String> names = Arrays.asList("Charlie", "Alice", "Bob");

// 알파벳 순 정렬
names.stream()
.sorted()
.forEach(System.out::println); // Alice, Bob, Charlie

// 알파벳 역순 정렬
names.stream()
.sorted(Comparator.reverseOrder())
.forEach(System.out::println); // Charlie, Bob, Alice

4. 자르기: limit, skip

  • limit(long maxSize): 파이프라인의 결과로 지정한 개수만큼만 가져옵니다.
  • skip(long n): 파이프라인의 처음 요소부터 지정한 개수만큼은 건너뜁니다.
IntStream.rangeClosed(1, 10)  // 1부터 10까지
.skip(3) // 1, 2, 3을 건너뜀 (4부터 시작)
.limit(2) // 2개만 취함
.forEach(System.out::println); // 4, 5 출력

이처럼 다양한 중간 연산 메서드들을 레고 블럭처럼 조립하여 강력한 파이프라인을 구축할 수 있습니다.

Advertisement