Goal
- stream에 대해 알아본다
- stream의 구조와 연산 종류에 대해 알아본다
- stream의 특징에 대해 알아본다
stream 이란?
연속되 정보를 처리하는데 사용된다. 즉, 컬렉션, 배열 등의 데이터 요소를 처리하는 기능을 제공한다. 배열에는 스트림을 사용할 수 없지만 배열을 컬렉션의 List로 변환하는 방법이 존재한다.
배열 to 컬렉션의 List
Integer[] values = {1,3,5};
List<Integer> list = new ArrayList<Integer>(Arrays.asList(values));
List<Integer> list = Arrays.stream(values).collect(Collectors.toList());
stream 구조
list.stream().filter(x-> x>10).count()
1. 스트림 생성 2. 중개 연산 3. 종단 연산
- 스트림 생성 : 컬렉션의 목록을 스트림 객체로 변환한다. 스트림 객체는 java.util.stream 패키지의 Stream 인터페이스를 말하며, stream() 메소드는 Collection 인터페이스에 선언되어 있다.
- 중개 연산 : 생성된 스트림 객체를 사용하여 중개 연산 부분에서 처리한다. 하지만 이 부분에서는 결과를 리턴하지 못한다.
- 종단 연산 : 마지막으로 중개 연산에서 작업된 내용을 바탕으로 결과를 리턴한다.
stream 연산의 종류
연산 종류 | 연산자 | 설명 |
중간 연산 | filter(pred) | 데이터를 조건으로 거를 때 사용 |
map(mapper) | 데이터를 특정 데이터로 변환 | |
flatMap(flat-mapper) | 스트림을 데이터를 잘개 쪼개 새로운 스트림 제공 | |
sorted(comparator) | 데이터 정렬 | |
distinct() / peek() / skip() | ||
종단 연산 |
foreach(block) | for 루프를 수행하는 것처럼 각각의 항목을 꺼냄 |
toArray(array-factory) | 배열로 변환 | |
any / all / noneMatch(pred) | 일치하는 것을 찾음 | |
findFirst / Any(pred) | 맨 처음이나 순서와 상관없는 것을 찾음 | |
reduce(binop) / reduce(base, binop) | 결과를 취합 | |
collect(collector) | 원하는 타입으로 데이터를 리턴 |
stream 특징
1. 원본의 데이터를 변경하지 않는다.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * 2);
stream.forEach(System.out::println);
Stream은 요소들의 연속적인 처리를 위한 파이프라인이다. 즉, Stream의 연산들은 원본 데이터를 변경하지 않고, 새로운 Stream을 반환한다.
2. Stream은 immutable(불변)한 특성을 가지고 있다.
따라서 원본 데이터를 변경하는 대신, Stream의 연산들은 원본 데이터로부터 새로운 Stream을 생성하여 처리한다.
이는 함수형 프로그래밍의 원칙 중 하나인 "불변성(Immutability)"을 따른다.
3. 재사용 불가
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * 2);
stream.forEach(System.out::println);
// 아래 코드는 컴파일 에러가 발생
stream.forEach(System.out::println);
Stream은 요소들의 연속적인 처리를 위한 파이프라인이므로, 한 번 소비된 요소들은 소비된 상태로 유지. 따라서 한 번 사용된 Stream은 다시 사용할 수 없다. 만약 동일한 데이터에 대해 다른 연산을 수행하고 싶다면, 새로운 Stream을 생성해야함.
4.내부 반복으로 작업을 처리
내부 반복 작업을 통해 Stream은 요소들의 처리를 효율적으로 처리하며, for, while문을 작성하지 않고도 Stream의 메서드를 활용하여 요소들을 다룰 수 있다. 또한, Stream은 병렬 처리(parallel processing)를 지원하여 대용량 데이터의 처리를 효율적으로 수행할 수 있다.