[Java] 숫자형 스트림
이전에 reduce를 활용한 코드를 살펴보았다.
Optional<Integer> max = numbers.stream().reduce(Integer::max);
하지만 위 코드는 박싱 비용이 있다. 즉, 내부적으로 계산하기 전에 Integer를 기본형으로 언박싱해야 한다.
그렇지만 걱정할 필요없다. 스트림은 숫자 스트림을 효율적으로 처리할 수 있도록 기본형 특화 스트림을 제공한다.
기본형 특화 스트림
Java 8에서는 IntStream, DoubleStream, LongStream 이렇게 세 가지 기본형 특화 스트림을 제공하며 합계, 최대, 최소 등을 계산하는 sum, max, min 등의 리듀싱 연산 수행 메서드도 제공한다. 또 기본형 스트림에서 다시 객체 스트림으로 복원하는 기능도 제공한다.
다만, 특화 스트림은 오직 박성 과정에서 일어나는 효율성과 관련 있으며 스트림에 추가 기능을 제공하지는 않는다.
숫자 스트림 매핑
int fees = movies.stream()
.mapToInt(Movie::getFee)
.sum();
위에서 mapToInt 메서드는 각 영화에서 모든 요금을 추출한다음, IntStream을 반환한다. 따라서 IntStream 인터페이스에서 제공하는 sum 메서드를 이용해서 칼로리 합계를 계산할 수 있다. 만약, 스트림이 비어있다면 sum은 기본값 0을 반환한다.
복원
IntStream의 map 연산은 int를 인수로 받아서 int를 반환하는 람다(IntUnaryOperator)를 인수로 받는다. 하지만 정수가 아닌 Movie 같은 다른 값을 반환하고 싶다면 스트림 인터페이스에 정의된 일반적인 연산을 사용해야 한다.
다음과 같이 특화 스트림을 일반 스트림으로 변환할 수 있다.
IntStream intStream = movies.stream().mapToInt(Movie::getFee);
Stream<Integer> stream = intStream.boxed();
Default: OptionalInt
sum 예제에서는 0이라는 기본값이 있었으므로 문제가 없었지만, IntStream에서 최댓값을 찾을 때는 0이라는 기본값 때문에 잘못된 결과가 도출될 수 있다.
그럼 스트림에 요소가 없는 상황과 실제 최댓값이 0인 상황을 어떻게 구분할까?
스트림은 OptionalInt, OptionalDouble, OptionalLong과 같이 기본형 특화 스트림에 사용할 수 있는 클래스가 있다.
OptionalInt maxFee = movies.stream()
.mapToInt(Movie::getFee)
.max();
int max = maxFee.orElse(-1);
숫자 범위
IntStream과 LongStream에서는 range와 rangeClosed라는 정적 메서드를 제공한다. 이 두 메서드는 시작값과 종료값을 인수로 받는다.
두 메서드의 차이는 range는 시작값과 종료값이 결과에 포함되지 않고, rangeClosed는 포함된다는 점이다.
다음과 같이 1부터 100까지의 숫자를 만들 수 있다.
IntStream evenNumbers = IntStream.rangeClosed(1, 100)
.filter(n -> n % 2 == 0);
'Language > Java' 카테고리의 다른 글
[Java] Java 9 특징 (0) | 2023.04.13 |
---|---|
[Java] Java 8 특징 (0) | 2023.04.13 |
[Java] 스트림 연산 (0) | 2023.04.07 |
[Java] HttpServlet (0) | 2023.04.06 |
[Java] 스트림(Stream) (0) | 2023.04.06 |
댓글
이 글 공유하기
다른 글
-
[Java] Java 9 특징
[Java] Java 9 특징
2023.04.13 -
[Java] Java 8 특징
[Java] Java 8 특징
2023.04.13 -
[Java] 스트림 연산
[Java] 스트림 연산
2023.04.07 -
[Java] HttpServlet
[Java] HttpServlet
2023.04.06