Java8 Stream 활용 방안을 정리합니다.
스트림을 활용하면 외부 반복 을 내부 반복 으로 바꿀 수 있어 좀 더 직관적인 코드를 작성할 수 있습니다. 또한 병렬로 수행할지 여부를 결정할 수 있습니다.
본문에서는 스트림 API를 활용하는 방법을 정리합니다.
필터링과 슬라이싱
- filter()
- distinct()
- limit()
- skip()
1 |
|
매핑
- map()
- flatMap() : 각 배열을 스트림이 아니라 스트림의 컨텐츠로 매핑한다.
1 |
// ** 스트림의 각 요소에 함수 적용하기 ** |
검색과 매칭
- allMatch()
- anyMatch()
- noneMatch()
- findFirst()
- findAny() : 현재 스트림에서 임의의 요소를 반환. 병렬 스트림에서는 첫 번째 요소를 찾기 어렵기 때문에 제약이 적은 findAny를 사용한다.
allMatch(), anyMatch(), noneMatch() 메서드는 자바의 &&
, ||
연산 처럼 활용된다.
1 |
// ** Predicate가 적어도 한 요소와 일치하는지 확인 ** |
리듀싱
- reduce()
reduce 메서드는 병렬 처리가 가능하다는 장점이 있다.
1 |
// ** 요소의 합 ** |
연산 | 형식 | 반환 형식 | 사용된 함수형 인터페이스 형식 | 함수 디스크립터 |
---|---|---|---|---|
filter | 중간 연산 | Stream |
Predicate |
T -> boolean |
distinct | 중간 연산 (상태 있는 언바운드) |
Stream |
||
skip | 중간 연산 (상태 있는 언바운드) |
Stream |
Long | |
limit | 중간 연산 (상태 있는 언바운드) |
Stream |
Long | |
map | 중간 연산 | Stream |
Function<T, R> | T -> R |
flatMap | 중간 연산 | Stream |
Function<T, Stream |
T -> Stream |
sorted | 중간 연산 (상태 있는 언바운드) |
Stream |
Comparator |
(T, T) -> int |
anyMatch | 최종 연산 | boolean | Predicate |
T -> boolean |
noneMatch | 최종 연산 | boolean | Predicate |
T -> boolean |
allMatch | 최종 연산 | boolean | Predicate |
T -> boolean |
findAny | 최종 연산 | Optional |
||
findFirst | 최종 연산 | Optional |
||
forEach | 최종 연산 | void | Consumer |
T -> void |
Collect | 최종 연산 | R | Collector<T, A, R> | |
Reduce | 최종 연산 (상태 있는 언바운드) |
Optional |
BinaryOperator |
(T, T) -> T |
count | 최종 연산 | long |
숫자형 스트림
기본형 특화 스트림
Java8에는 박싱 비용을 줄이고 sum, max와 같이 자주 사용되는 숫자 관련 리듀싱 연산 메서드를 함께 제공하는 세 가지 기본형 특화 스트림을 제공한다.
- IntStream
- DoubleStream
- LongStream
- OptionalInt
- OptionalDouble
- OptionalLong
1 |
// ** 숫자 스트림으로 매핑 ** |
숫자 범위
IntStream과 LongStream은 특정 범위의 숫자를 이용하기 위한 2가지 정적 메서드를 제공한다. :
- range(시작값, 종료값) : 결과에 시작값, 종료값 미포함
- rangeClosed(시작값, 종료값) : 결과에 시작값, 종료값 포함
1 |
IntStream evenNumbers = IntStream.rangeClosed(1, 100) // 1~100 |
스트림 만들기
값으로 스트림 만들기
- Stream.of() : 임의의 수로 인수를 받아 스트림으로 만든다.
- Stream.empty() : 스트림을 비운다.
1 |
Stream<String> stream = Stream.of("Java 8", "Lambdas", "In", "Action"); |
배열로 스트림 만들기
- Arrays.stream()
1 |
int[] numbers = {2, 3, 5, 7, 11, 13}; |
파일로 스트림 만들기
NIO API(비블록 I/O)도 스트림 API를 활용할 수 있게 되었다.
java.nio.file.Files의 많은 정적 메서드가 스트림을 반환한다. (ex> Files.lines
)
1 |
// 파일에서 고유한 단어 수를 찾는 프로그램 |
함수로 무한 스트림 만들기
스트림 API는 함수에서 스트림을 만들 수 있는 두 개의 정적 메서드를 제공한다.
이전에 봤던 크기가 고정된 컬렉션과는 달리 크기가 고정되지 않은 무한 스트림(Infinite Stream) 을 만들 수 있다. (언바운드 스트림(Unbounded Stream))
따라서 반드시 limit(n)
함수와 함께 사용해야 한다.
- Stream.iterate()
- 초기값과 람다를 인수로 받아서 새로운 값을 끊임없이 생산한다.
- 일반적으로 연속된 일련의 값을 만들 때 사용한다.
- Stream.generate()
- Supplier
를 인수로 받아서 새로운 값을 생산한다.
- Supplier
1 |
// iterate |
近期评论