[JAVA]숫자형 스트림 (IntStream, DoubleStream ..)

2022. 10. 13. 15:56 JAVA BASIC/Lambda&Stream(람다와 스트림)

메뉴의 칼로리 합계를 reduce로 구할 수 있다.

int calories = menu.stream()
        .map(Dish::getCalories)
        .reduce(0, Integer::sum);

사실 위 코드에는 박싱 비용이 숨어 있다. 내부적으로 합계를 계산하기 전에 Integer를 기본형으로 언박싱해야 한다.

int calories = menu.stream()
        .map(Dish::getCalories)
        .sum();

위와 같이 sum 메소드를 호출 할 수 없을까? map 메서드가 Stream<T>를 생성하기 때문에 불가능 하다.

스트림의 요소 형식은 Integer 지만 (Stream<Integer>) 인터페이스에는 sum 메서드가 없다. 다행히 스트리 API 숫자 스트림을 효율적으로 처리할 수 있도록 기본형 특화 스트림(primitive stream specialization)을 제공한다.

1. 기본형 특화 스트림

스트림 API는 박싱 비용을 피할 수 있도록 IntStream, DoubleStream, LongStream을 제공한다.

각각의 인터페이스는 숫자 스트림의 합계를 계산하는 sum, max 같이 자주 사용하는 숫자 관련 리듀싱 연산 수행 메서드를 제공한다.

숫자 스트림으로 매핑

int calories = menu.stream() // Stream<Dish> 반환
        .mapToInt(Dish::getCalories) // IntStream 반환
        .sum();

Intstream은 max, min, average 등 다양한 유틸리티 메서드를 지원한다.

객체 스트림으로 복원하기

boxed 메서드를 이용해서 특화 스트림을 일반 스트림으로 변환할 수 있다.

IntStream intstream = menu.stream().mapToInt(Dish::getCalories); // 스트림을 숫자 스트림으로 변환
Stream<Integer> stream = intstream.boxed(); // 숫자 스트림을 스트림으로 변환

기본값 : OptionalInt

스트림에 요소가 없는 경우를 고려해서 OptionalInt를 이용할 수 있다.

OptionalInt maxCalories = menu.stream().mapToInt(Dish::getCalories).max();
int max = maxCalories.orElse(1);

2. 숫자 범위

1에서 100 사이의 숫자를 생성한다고 가정하자. IntStream, LongStream에서는 range, rangeClosed라는 두 가지 정적메서드를 제공한다. (range는 시적값과 종료값이 결과에 포함되지않지만, rangeClosed는 시작과 종료값이 결과에 포함된다.)

IntStream evenNumbers = IntStream.rangeClosed(1, 100)
                                        .filter(n -> n % 2 == 0);
System.out.println(evenNumbers.count());

출처 : 모던자바인액션

출처: https://cornswrold.tistory.com/545 [평범한개발자노트:티스토리]