스트림(Stream)이란 무엇인가
스트림은 자바 8에서 도입된 기능으로 컬렉션(Collection)과 같은 데이터 소스를 함수형 프로그래밍 방식으로 처리할 수 있도록 도와주는 API 이걸 사용해 데이터를 필터링, 매핑, 정렬, 집계 등 빠르고 직관적으로 수행가능
컬렉션(Collection) 인터페이스에 디폴트(Default) 메서드로 stream()이 정의돼있는데 이 메서드를 사용해서 해당 컬렉션의 데이터 흐름인 Stream을 만들 수 있다.
List<String> list = Arrays.asList("apple", "banana", "orange");
// 컬렉션을 스트림으로 변환하여 각 요소를 출력
list.stream().forEach(System.out::println); // apple, banana, orange 출력
스트림의 특징 3가지
1. 지연 연산: 중간연산은 지연연산, 최종연산이 호출 전까지는 데이터를 처리하지 않는다.
-> 성능 최적화
2. 일회성: 만들어진 스트림은 한 번의 연산 후 더 이상 사용할 수 없다.
-> 그래서 일반적으로 set.stream()으로 변수에 넣지 않고 바로 사용
3. 순차 또는 병렬 처리: 순차 처리 기본, parallelStream()을 통해 병렬 스트림 생성하여 동시에 처리 가능
스트림 연산 종류
1. 중간 연산(Intermediate Operations)
중간 연산은 스트림 변형, 필터링 연산
- filter(): 조건에 맞는 요소만 남기기
- map(): 각 요소 다른 형태로 변환
- sorted(): 요소 정렬
- distinct(): 중복제거
2. 최종연산 (Terminal Operation)
스트림의 연산을 완료하고 결과 반환, 이 이후 해당 스트림은 사용 불가(일회성)
- forEach(): 각 요소에 대해 작업 수행
- collect(): 스트림을 컬렉션이나 다른 형태로 변환
- reduce(): 스트림 요소를 하나로 합침
스트림 장점
- 간결한 코드: 복잡한 반복문 대신 간결한 함수형 코드 작성 가능
- 함수형 프로그래밍 지원: filter(), map(), reduce() 같은 연산을 통해 데이터를 선언적 처리
- 병렬 처리: 병렬 스트림을 통해 빠르게 처리
외부 반복 VS 내부 반복
외부 반복: for, while 과 같은 원래 쓰던 반복
내부 반복: 스트림을 사용하여 데이터를 처리하는 방식 데이터의 순회와 처리는 스트림에서 처리
차이점 요약
1. 제어권의 차이
외부: 개발자가 반복 설계
내부: 스트림이 알아서, 처리 로직만 제공하면 됨
2. 코드의 간결함
외부: 코드 장황
내부: 간결
3. 병렬 처리
외부: 스레드 관리 수동관리
내부: 병렬 스트림 통해 병렬처리 간편
연습코드
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamExample {
public static void main(String[] args) {
// 리스트 초기화
List<String> fruits = Arrays.asList("apple", "banana", "avocado", "grape", "orange");
// 1. 'a'로 시작하는 문자열 필터링
// 2. 각 문자열을 대문자로 변환
// 3. 결과를 알파벳 순으로 정렬
// 4. 결과를 리스트로 수집
List<String> result = fruits.stream() // 스트림 생성
.filter(s -> s.startsWith("a")) // 'a'로 시작하는 문자열 필터링
.map(String::toUpperCase) // 대문자로 변환
.sorted() // 정렬
.collect(Collectors.toList()); // 리스트로 수집
// 결과 출력
System.out.println(result); // [APPLE, AVOCADO]
// 숫자 리스트 초기화
List<Integer> numbers = Arrays.asList(1, 2, 3, 3, 4, 5, 6);
// 1. 중복된 값 제거 (distinct)
// 2. 3보다 큰 숫자만 필터링
// 3. 처음 2개를 제외하고 나머지를 출력
numbers.stream()
.distinct() // 중복 제거
.filter(n -> n > 3) // 3보다 큰 숫자 필터링
.skip(2) // 처음 2개를 건너뛰기
.forEach(System.out::println); // 결과 출력: 6
// 숫자 합계 계산
int sum = numbers.stream()
.reduce(0, Integer::sum); // 스트림 요소의 합 계산
System.out.println("Sum: " + sum); // 합계 출력: Sum: 24
}
}
'공부일지 > Java' 카테고리의 다른 글
Java 익명클래스, 람다식, 메서드 참조, 근데 이제 map()을 곁들인 (0) | 2024.10.26 |
---|---|
[JAVA] Arrays.asList() (0) | 2024.07.04 |
[JAVA] String, StringBuffer, StringBuilder (0) | 2024.07.01 |
[JAVA] 6/21에 배운 것 (0) | 2024.06.26 |
[JAVA] 6/20 배운거 클래스 (0) | 2024.06.20 |