카테고리 없음
[Java Stream Programming] 8.Reducing, Primitive Stream
코딩펭귄
2024. 2. 14. 16:56
Reducing
- 스트림의 요소로 집계함
요소의 합 구하기
일반 Java에서 합계 구하는 코드
int sum = 0;
for (int x : numbers) {
sum += x;
}
리듀싱 활용한 코드
int sum = numbers.stream().reduce(0, (a, b) -> a + b);
a:집계된 값 / b : 스트림 요소의 값
처음에는 0 -> a에 들어감
Reducing 처리과정
최대값과 최소값
Integer::max , Integer::min 이용
ex) Optional<Integer> max = numbers.stream().reduce(Integer::max);
(Optional을 주는 이유 : 데이터가 있을수도, 없을수도 있으므로)
-- 단, Optional 쓰지 않고, .orElse(0) / .orElse(null) 등을 추가해주는 방법을 더 많이 씀
public class ReduceExample {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(4);
numbers.add(5);
numbers.add(3);
numbers.add(9);
//총 합계
//초기값0이 int이기 때문에 sumResult가 int가 됨
int sumResult = numbers.stream().reduce(0, (sum, item) -> sum + item); //sum:집계된 값, item:반복되는 값
//0이 좌측sum으로 할당되면 : sum이 우측sum으로, item은 우측item으로 가고 이 합계는 다시 좌측sum에 할당됨
System.out.println(sumResult);
//최대값 구하기
int maxNumber = numbers.stream()
.reduce(Integer::max)
.orElse(0); //Optional<Integer>max = 라고 쓰지않고, 이렇게 표현해줌
System.out.println(maxNumber);
//최소값 구하기
int minNumber = numbers.stream()
.reduce(Integer::min)
.orElse(0);
System.out.println(minNumber);
}
}
스트림의 중간연산과 최종연산
반환타입에 따라 중간연산, 최종연산으로 나뉨
Stream을 반환시키면 : 중간연산, 그 이외 : 최종연산
Primitive Stream
- int, double, long특화 스트림 제공
-- 리듀싱관련 메소드 제공
-- 기본형 특화스트림(Primitive stream) -> 일반스트림 변환메소드 제공
숫자스트림으로 맵핑하기
int calories = menu.stream() // Stream<Dish> 반환
.mapToInt(Dish::getCalories) // IntStream 반환
.sum();
ex) mapToInt() : IntStream 반환, mapToDouble() : doubleStream 반환, mapToLong() : LongStream 반환
객체스트림으로 복원하기
스트림을 -> 숫자스트림으로, 이걸 -> 일반스트림으로
// 스트림을 숫자 스트림으로 변환
IntStream IntStream = menu.stream().mapToInt(Dish::getCalories);
// 숫자 스트림을 일반 스트림으로 변환
Stream<Integer> stream = IntStream.boxed();
기본값 처리
- OptionalInt, OptionalDouble, OptionalLong 제공
- Optional의 orElse를 사용할수도 있다 (위 코드에서 .orElse(0) / .orElse(null)해주면 간편하게 해결가능 -> Optional 추가 안해줘도 됨)
PrimitiveStream 사용예제
package ch07.primitivestream;
import java.util.List;
import fp_java.ch02.stream.vo.Dish;
import fp_java.ch02.stream.vo.DishData;
public class PrimitiveStreamExample {
public static void main(String[] args) {
List<Dish>menu = DishData.menu;
//일반스트림으로 모든메뉴들의 칼로리 총합 구해보기
int calories = menu.stream() //Stream<Dish>
// .map((dish)-> dish.getCalories()) //Stream<Integer>
.map(Dish::getCalories) // Stream<Integer>
.reduce(0, (sumCalories, calory) -> sumCalories + calory);
System.out.println(calories);
//PrimitiveStream으로 모든 메뉴들의 칼로리 총 합 구해보기
calories = menu.stream() //Stream<Dish>
// .mapToInt((dish) -> dish.getCalories()) //IntStream
.mapToInt(Dish::getCalories) //IntStream
.sum();
System.out.println("모든 메뉴들의 칼로리 총 합: " + calories);
//primitiveStream으로 채식메뉴들의 칼로리 총합 구해보기
calories = menu.stream()
// .filter(dish -> dish.isVegetarian())
.filter(Dish::isVegetarian)
// .mapToInt(dish -> dish.getCalories())
.mapToInt(Dish::getCalories)
.sum();
System.out.println("채식메뉴들의 칼로리 총 합: " + calories);
//primitiveStream으로 채식메뉴들의 평균칼로리 구해보기
double averagecalories = menu.stream()
.filter(Dish::isVegetarian)
.mapToInt(Dish::getCalories)
.average()
.orElse(0);
System.out.println("채식메뉴들의 평균 칼로리: " + averagecalories);
}
}