Chapter 6 - 스트림으로 데이터 수집
2022. 9. 25. 16:32ㆍ개발 관련 책 읽기/모던 자바 인 액션
✅ 아래 내용들에 대해서 알아보자
- Collectors 클래스로 컬렉션을 만들고 사용하기
- 하나의 값으로 데이터 스트림 리듀스하기
- 특별한 리듀싱 요약 연산
- 데이터 그룹화와 분할
- 자신만의 커스텀 컬렉션 개발
모든 실습 내용은 깃허브(아래 링크)에 있습니다. 참고 부탁드립니다 😀😀
컬렉터란 무엇인가?
컬렉터(Collector) 인터페이스 구현은 스트림의 요소를 어떤 식으로 도출할지 지정한다.
예를들어, toList()를 사용하면 각 요소를 리스트로 만들어라는 의미로 사용가능하다.
collect를 호출하면 컬렉터가 스트림의 요소에 reducing 연산을 수행하여 데이터 구조를 도출할 수 있다.
자 그러면 간단한 예시 코드를 보면서 이해해보자.
짝수를 필터링하여 collect(toList()) 를 사용하여 List<Integer>로 변환하는 코드를 볼 수 있다.
@DisplayName("고유 요소로 이루어진 스트림 짝수 필터링")
@Test
public void filterEvenNumber() {
//given
List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
//when
List<Integer> evenNumbers = numbers.stream()
.filter(num -> num % 2 == 0)
.distinct() //중복 제거
.collect(toList());
//중복 제거 된 짝수 출력
evenNumbers.stream()
.forEach(System.out::println);
//then
assertThat(evenNumbers.size()).isEqualTo(2);
}
Collectors에서 제공하는 메서드의 기능은 크게 3가지로 구분된다.
- 스트림 요소를 하나의 값으로 리듀싱 및 요약
- 요소 그룹화
- 요소 분할
하나하나씩 알아보자.
리듀싱
counting을 활용하여 음식들의 개수를 계산하는 하는 코드이다.
/**
* 6.2.0 - 요리 개수 구하기 (202p)
*/
@DisplayName("counting() 활용한 요리 계수 구하기")
@Test
public void getFoodCount() {
//given
// Long collect = menu.stream().count();
Long foodCount = menu.stream()
.collect(Collectors.counting());
//when
System.out.println("foodCount = " + foodCount);
//then
assertThat(foodCount).isEqualTo(9);
}
가장 칼로리가 높은 음식을 찾는 예시 코드를 보자
collect와 Collectors.maxBy, minBy를 사용하여 칼로리가 가장 높은/낮은 음식을 찾을 수 있다.
/**
* 6.2.1 - 스트림값에서 최대값 최소값 검색 (202p)
*/
@DisplayName("가장 칼로리가 높은 요리 찾기")
@Test
public void findHighestCalFoodWithComparingInt() {
//given
/**
* 스트림 요소를 비교하는 데 Compareator.comparingint를 사용하고 파라미터로 Dish의 칼로리로 비교한다
* 그 후 maxBy를 사용하여 파라미터로 Compertator를 넘긴 후 maxBy는 Reducing 사용하여 최대값을 구한다
*/
Dish dish = menu.stream()
.collect(Collectors.maxBy(Comparator.comparingInt(Dish::getCalories)))
.orElse(null);
//when
System.out.println("dish = " + dish);
//then
assertThat(dish).isNotNull();
}
요약 연산
Collectors 클래스는 summingInt라는 특별한 요약 팩토리 메서드를 제공한다.
summinInt는 객체 -> int로 매핑하는 함수를 인수로 받아 객체를 int로 매핑한 컬렉터를 반환한다.
아래는 summinInt를 활용한 음식들의 총 칼로리를 구하는 예시이다.
/**
* 6.2.2 - 요약 연산 (203p)
*/
@DisplayName("요약 연산을 할용한 음식 총 칼로리 구하기")
@Test
public void findTotalCalWithSummarization() {
/**
* 1. summingInt는 객체를 int로 매핑하는 함수를 인수로 받는다.
* 2. 인수로 전달 된 함수는 객체를 int로 매핑한 컬렉터를 반환한다.
* 3. 그 후 summingInt가 collect메서드로 전달되면 합계 작업을 수행한다.
*/
//given
Integer totalCalories = menu.stream()
.collect(summingInt(Dish::getCalories));
// int sum = menu.stream()
// .mapToInt(Dish::getCalories)
// .sum();
//when
System.out.println("totalCalories = " + totalCalories);
//then
}
반응형
'개발 관련 책 읽기 > 모던 자바 인 액션' 카테고리의 다른 글
Chapter 5 - 스트림 활용(2편) (0) | 2022.11.08 |
---|---|
Chapter 7 - 병렬 데이터 처리와 성능 (0) | 2022.11.07 |
Chapter 5 - 스트림 활용(1편) (0) | 2022.09.04 |
Chapter 4 - 스트림 소개 (0) | 2022.08.22 |
Chapter 3 - 람다 표현식 (0) | 2022.08.22 |