안녕하세요 알통몬입니다. 공감 및 댓글은 포스팅 하는데 아주아주 큰 힘이 됩니다!! 포스팅 내용이 찾아주신 분들께 도움이 되길 바라며 더 깔끔하고 좋은 포스팅을 만들어 나가겠습니다^^ |
집계란 :
최종 처리 기능으로써 요소들을 처리해 합계, 평균 값 같이 하나의 값으로 산출하는 것입니다.
=> 많은 양의 데이터를 가공해 출소하는 리덕션이라고 볼 수 있습니다.
스트림은 기본 집계 메소드를 제공합니다.
OptionalXXX 의 종류는 Optional, OptionalInt, OptionalLong, OptionalDouble 타입이 있고,
값을 저장하는 값 기반 클래스들입니다.
이 겍체에서 값을 얻으려면 get(), getAsDouble(), getAsInt, getAsLong()를 호출하면 됩니다.
예제)
import java.util.Arrays;
public class Example {
public static void main(String[] args) {
long count = Arrays.stream(new int[] {1, 2, 3, 4, 5})
.filter(n -> n%2==0)
.count();
System.out.println("2의 배수 개수: " + count);
long sum = Arrays.stream(new int[] {1, 2, 3, 4, 5})
.filter(n -> n%2==0)
.sum();
System.out.println("2의 배수의 합: " + sum);
double avg = Arrays.stream(new int[] {1, 2, 3, 4, 5})
.filter(n -> n%2==0)
.average()
.getAsDouble();
System.out.println("2의 배수의 평균: " + avg);
int max = Arrays.stream(new int[] {1, 2, 3, 4, 5})
.filter(n -> n%2==0)
.max()
.getAsInt();
System.out.println("최대값: " + max);
int min = Arrays.stream(new int[] {1, 2, 3, 4, 5})
.filter(n -> n%2==0)
.min()
.getAsInt();
System.out.println("최소값: " + min);
int first = Arrays.stream(new int[] {1, 2, 3, 4, 5})
.filter(n -> n%3==0)
.findFirst()
.getAsInt();
System.out.println("첫번째 3의 배수: " + first);
}
}
OptionalXXX 클래스들은 저장하는 값의 타입만 다르고 제공하는 기능은 거의 같습니다.
집계값만 저장하는 것이 아니라 집계 값이 없을 경우 디폴트 값을 설정할 수도 있고,
집계값을 처리하는 Consumer도 등록할 수 있습니다.
Optional 클래스에서 제공하는 메소드
컬렉션의 요소가 동적으로 추가되는 경우가 많습니다. 컬렉션의 요소가 추가되지 않아
저장된 요소가 없을 경우 집계 메소드를 사용할 수는 없고, 사용할게 되면 NoSuchElementException
예외가 발생하게 됩니다. 요소가 없는 경우에 예외를 피하는 방법이 세가지 있습니다.
- Optional 객체를 얻어 isPresent() 로 평균값 여부를 확인합니다.
- orElse() 로 디폴트 값을 지정합니다.
- ifPresent() 로 평균값이 있을 경우에만 값을 이용하는 람다식을 실행합니다.
예제)
import java.util.ArrayList;
import java.util.List;
import java.util.OptionalDouble;
public class Example {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
/*//예외 발생(java.util.NoSuchElementException)
double avg = list.stream()
.mapToInt(Integer :: intValue)
.average()
.getAsDouble(); // 컬렉션 요소에 저장된 값이 없기 때문에
*/
//1
OptionalDouble optional = list.stream()
.mapToInt(Integer :: intValue)
.average();
if(optional.isPresent()) {
System.out.println("평균: " + optional.getAsDouble());
} else {
System.out.println("평균: 0.0");
}
//2
double avg = list.stream()
.mapToInt(Integer :: intValue)
.average()
.orElse(0.0);
System.out.println("평균: " + avg);
//3
list.stream()
.mapToInt(Integer :: intValue)
.average()
.ifPresent(a -> System.out.println("평균: " + a));
}
}
스트림에서는 기본 집계 말고도 프로그램화해서 다양한 집계 결과물을 만들 수 있도록,
reduce() 도 제공합니다.
만약 스트림의 요소가 없다면 디폴트 값인 indentity 매개 값이 리턴됩니다.
예제)
import java.util.Arrays;
import java.util.List;
public class Example {
public static void main(String[] args) {
List<Student> studentList = Arrays.asList(
new Student("티스토리", 77),
new Student("블로그", 97),
new Student("알통몬", 78)
);
int sum1 = studentList.stream()
.mapToInt(Student :: getScore)
.sum();
int sum2 = studentList.stream()
.map(Student :: getScore)
.reduce((a, b) -> a+b)
.get();
int sum3 = studentList.stream()
.map(Student :: getScore)
.reduce(0, (a, b) -> a+b);
System.out.println("sum1: " + sum1);
System.out.println("sum2: " + sum2);
System.out.println("sum3: " + sum3);
}
}
public class Student {
private String name;
private int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
public String getName() { return name; }
public int getScore() { return score; }
}
이상입니다.