기본집계()
집계(Aggregate)는 최종 처리 기능으로 요소들을 처리해서 카운팅, 합계, 평균값, 최대값, 최소값 등과 같이 하나의 값으로 산출하는 것을 말한다.
집계는 대량이 데이터를 가공해서 축소하는 리덕션(Reduction) 이라고 볼수 있다.
스트림이 제공하는 기본 집계
이 집계 메소드에서 리턴하는 OptionalXXX 는 자바 8에 추가한 java.util 패키지의 Optional, OptionalDouble, OptionallInt, OptionallLong 클래스 타입을 말한다.
이들은 값을 저장하는 값 기반 클래스(value-based class)들이다
이객체에서 값을 얻기 위해서는 getAsDouble(), getAsInt(), getAsLong() 을 호출하면 된다
package Stream;
import java.util.Arrays;
public class AggregateExample {
public static void main(String[] args) {
long count = Arrays.stream(new int[] {2,4,6,8,10}).filter(n->n%2 ==0).count();
System.out.println("count : " + count);
long sum = Arrays.stream(new int[] {1,2,3,4,5}).filter(predicate -> predicate % 2 == 0).sum();
System.out.println("sum : " + sum);
double average = Arrays.stream(new int[] {1,2,3,4,5}).filter(predicate -> predicate % 2 == 0).average().getAsDouble();
System.out.println("average : " + average);
int max = Arrays.stream(new int[] {1,2,3,4,5}).filter(predicate -> predicate % 2 == 0).max().getAsInt();
System.out.println("max" + max);
int min = Arrays.stream(new int[] {1,2,3,4,5}).filter(predicate -> predicate % 2 == 0).min().getAsInt();
System.out.println("min" + min);
int first = Arrays.stream(new int[] {1,2,3,4,5}).filter(predicate -> predicate % 2 == 0).findFirst().getAsInt();
System.out.println("first" + first);
}
}
Optional 클래스
Optional, OptionalDouble, OptionalInt, OptionalLong 클래스에 알아 보자
이 클래스들은 저장하는 값의 타입만 다를 뿐 제공하는 기능은 거의 동일하다.
Optional 클래스는 단순히 집계값만 저장하는 것이 아니라, 집계 값이 존재하지 않을 경우 디폴트 값을 설정 할 수도 있고,
집계 값을 처리하는 Consumer도 등록할 수 있다.
다음은 Optional 클래스들이 제공하는 메소드
컬렉션의 요소는 동적으로 추가되는 경우가 많다.
저장된 요소가 없을 경우 다음 코드는 어떻게 될까?
List<Integer> list = new ArrayList<>();
double avg = list.stream().mapToInt(Integer::intValue).average().getAsdouble();
System.out.println("평균 : " + avg);
요소가 없기 때문에 평균값도 있을 수 없다
NoSuchElementException 예외가 발생한다.
요소가 없을 경우 예외를 피하는 세가지 방법이 있다.
첫번재는 Optional 객체를 얻어 isPresent() 메소드로 평균값 여부를 확인 하는 것이다.
isPresent() 메소드가 true 를 리턴할때만 getAsDouble() 메소드로 평균값을 얻으면 된다.
OptionalDouble opitonal = list.stream().mapToInt(Integer::intValue).average();
if(opitonal.isPresnt()){
System.out.println("평균 : " + optional.getAsDouble());
} else {
System.out.println("평균 : " + 0.0);
}
두 번재 방법은 orElse() 메소드로 디폴트 값을 정해 놓는다.
평균값을 구할 수 없는 경우에는 orElse() 의 매개값이 디폴트 값이 된다
double avg = list.stream().mapToInt(Integer :: intValue).avaerage().orElse(0.0);
System.out.println("평균: " + avg );
세번재 방법은 ifPresent() 메소드로 평균값이 있을 경우에만 값을 이용하는 람다식을 실행
list.stream().mapToInt(Integer::intValue).average().ifPresent(a->System.out.println("평균: " + a));
package Stream;
import java.util.ArrayList;
import java.util.List;
import java.util.OptionalDouble;
public class OptionalExample {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
/*
* 예외 발생
*
* double avg
* =list.stream().mapToint(Integer::intValue).average().getAsDouble();
*
*/
// 방법 1
OptionalDouble OptionalDouble = list.stream().mapToInt(Integer::intValue).average();
if (OptionalDouble.isPresent()) {
System.out.println(OptionalDouble.getAsDouble());
} else {
System.out.println("No value");
}
// 방법 2
double avg = list.stream().mapToInt(Integer::intValue).average().orElse(0);
System.out.println("avg : " + avg);
//방법3
list.stream().mapToInt(Integer::intValue).average().ifPresent(System.out::println);
}
}
'Back-end > 이것이 자바다[신용권 한빛미디어]' 카테고리의 다른 글
수집(collect()) (1) | 2022.09.22 |
---|---|
커스텀 집계(reduce()) (0) | 2022.06.25 |
루핑(peek(), forEach()), 매칭 (allMatch(), anyMatch(), noneMatch()) (0) | 2022.06.02 |
필터링(distinct(), filter()), 매핑(mapXXX), 정렬(sorted) (0) | 2022.05.30 |
스트림 파이프라인 (0) | 2022.05.28 |