자바 8부터 등장한 스트림(Stream) API는 컬렉션 데이터를 효율적으로 처리할 수 있도록 설계된 기능입니다.
스트림을 활용하면 코드를 간결하게 작성할 수 있으며, 병렬 처리(Parallel Processing)도 용이합니다.
이번 포스트에서는 스트림의 개념과 내부 반복자, 중간 처리 & 최종 처리에 대해 자세히 알아보겠습니다.
✅ 17.1 스트림이란?
🎯 1. 스트림(Stream)이란?
스트림(Stream)은 "데이터의 흐름"을 의미합니다.
데이터가 하나씩 흐르면서 처리되는 방식을 제공하는 것이 스트림 API입니다.
✔ 객체를 하나씩 흘려보내면서 처리하는 개념
✔ 컬렉션(리스트, 셋 등)에서 데이터를 하나씩 읽어와 처리하는 방식
✔ 기존 for문, while문을 이용한 외부 반복 방식과 다르게 내부 반복을 사용
🎯 2. 기존 방식(외부 반복자) vs. 스트림(내부 반복자)
✅ 외부 반복자(기존 방식)
List<String> list = Arrays.asList("홍길동", "김길동", "박길동");
// for문 사용 (외부 반복자)
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 향상된 for문 사용
for (String name : list) {
System.out.println(name);
}
✔ for문을 사용하여 요소를 하나씩 가져와 직접 처리
✔ 데이터를 가져오는 작업이 코드에 포함됨 (수동적 반복)
✅ 내부 반복자(스트림 방식)
list.stream().forEach(name -> System.out.println(name));
✔ 데이터를 직접 가져오는 것이 아니라 "흘러가는 데이터"를 처리하는 방식
✔ 컬렉션 내부에서 자동으로 데이터를 하나씩 흘려보내면서 처리
✔ 람다식을 활용하여 간결한 코드 작성 가능
✅ 17.2 내부 반복자 (Internal Iterator)
스트림 API는 내부 반복자를 활용하여 데이터를 자동으로 처리합니다.
내부 반복자는 컬렉션 내부에서 요소를 처리하는 방식을 의미합니다.
🎯 1. 외부 반복자 vs 내부 반복자 비교
반복 방식 | 코드 예시 | 특징 |
외부 반복자 | for (String s : list) {} | 직접 요소를 하나씩 가져와서 처리 |
내부 반복자 | list.stream().forEach(s -> {}) | 요소가 스트림을 따라 자동으로 처리됨 |
🎯 2. 내부 반복자 코드 예제
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<String> list = Arrays.asList("홍길동", "김길동", "박길동");
// 스트림을 이용한 내부 반복자
list.stream().forEach(name -> System.out.println(name));
}
}
✔ 스트림을 생성한 후 forEach()를 통해 요소를 하나씩 처리
✔ 코드가 훨씬 간결해지고, 유지보수도 쉬워짐
🎯 3. 내부 반복자가 더 좋은 이유
✔ 코드가 간결하고 직관적
✔ 데이터를 가져오는 과정이 자동화됨 → 속도 향상
✔ 병렬 처리가 용이하여 성능 최적화 가능
✅ 17.3 중간 처리 & 최종 처리
🎯 1. 스트림의 처리 과정
스트림의 데이터 처리는 "중간 처리" → "최종 처리" 단계로 나뉩니다.
처리 단계 |
설명 | 예제 |
중간 처리 | 데이터를 가공하는 과정 (필터링, 변환 등) | filter(), map() |
최종 처리 | 데이터를 최종적으로 사용하는 과정 (출력, 집계 등) | forEach(), sum(), count() |
🎯 2. 중간 처리 (Intermediate Operations)
중간 처리는 스트림을 변환하는 과정입니다.
대표적인 중간 처리 메소드로는 filter(), map(), sorted() 등이 있습니다.
✅ 필터링(filter) 예제
List<String> names = Arrays.asList("홍길동", "김철수", "이영희");
// 이름이 "김"으로 시작하는 데이터만 필터링
names.stream()
.filter(name -> name.startsWith("김"))
.forEach(System.out::println);
✔ filter() : 조건에 맞는 요소만 걸러서 새로운 스트림 생성
✅ 변환(map) 예제
List<String> names = Arrays.asList("홍길동", "김철수", "이영희");
// 모든 이름을 대문자로 변환
names.stream()
.map(String::toUpperCase)
.forEach(System.out::println);
✔ map() : 요소를 다른 형태로 변환하여 새로운 스트림 생성
🎯 3. 최종 처리 (Terminal Operations)
최종 처리는 스트림의 데이터를 집계하거나 출력하는 과정입니다.
대표적인 최종 처리 메소드로는 forEach(), sum(), count(), average() 등이 있습니다.
✅ 집계(count, sum, average) 예제
import java.util.Arrays;
import java.util.List;
import java.util.OptionalDouble;
public class StreamAggregationExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(10, 20, 30, 40, 50);
// 개수 카운트
long count = numbers.stream().count();
System.out.println("개수: " + count); // 출력: 개수: 5
// 총합
int sum = numbers.stream().mapToInt(Integer::intValue).sum();
System.out.println("총합: " + sum); // 출력: 총합: 150
// 평균
OptionalDouble avg = numbers.stream().mapToInt(Integer::intValue).average();
System.out.println("평균: " + avg.getAsDouble()); // 출력: 평균: 30.0
}
}
✔ count() : 요소 개수 구하기
✔ sum() : 총합 구하기
✔ average() : 평균 구하기
🎯 4. 중간 처리 + 최종 처리 (스트림 파이프라인)
중간 처리와 최종 처리를 연결하여 사용(파이프라인)할 수 있습니다.
List<String> names = Arrays.asList("홍길동", "김철수", "이영희");
// "김"으로 시작하는 이름만 필터링 후 대문자로 변환하여 출력
names.stream()
.filter(name -> name.startsWith("김"))
.map(String::toUpperCase)
.forEach(System.out::println);
✔ 중간 처리(filter + map) : "김"으로 시작하는 데이터를 필터링 후 대문자로 변환
✔ 최종 처리(forEach) : 변환된 데이터를 출력
✅ 🎯 결론 (왜 스트림을 사용할까?)
✔ 내부 반복자 방식으로 데이터 처리 속도가 빠름
✔ 람다식과 함께 사용하여 코드가 간결하고 가독성이 좋음
✔ 필터링, 변환, 정렬, 집계 등 다양한 데이터 처리를 쉽게 구현 가능
✔ 병렬 처리(Parallel Processing)가 쉬움
참조:
이것이 자바다 _ 신용권
'Web Programming Language > JAVA' 카테고리의 다른 글
스트림(Stream) 활용 - 요소 정렬, 루핑(유소 개별 처리), 매칭(조건 만족 여부) (1) | 2025.03.06 |
---|---|
스트림(Stream) 활용 - 리소스로부터 스트림 얻기, 요소 걸러내기(필터링), 요소 변환(매핑) (0) | 2025.03.06 |
람다식(Lambda Expression) - 메소드 참조, 생성자 참조 (1) | 2025.03.05 |
람다식(Lambda Expression) - 매개변수가 없는 람다식, 매개변수가 있는 람다식, 리턴값이 있는 람다식 (0) | 2025.03.05 |
람다식(Lambda Expression)이란? (0) | 2025.03.05 |
댓글