시그마 삽질==six 시그마

Stream collect 3탄(그룹핑후 매핑 및 집계) 본문

프로그래밍/Java

Stream collect 3탄(그룹핑후 매핑 및 집계)

Ethan Matthew Hunt 2020. 8. 27. 22:50
해당글은 신용권님의 '이것이 자바다' 를 토대로 작성되었습니다.

예전에 남궁성님의 '자바의 정석' 그리고 신용권님의 '이것이 자바다' 두권 다 보았는데

저는 개인적으로 신용권님의 책이 좀 더 핵심을 찌르고 직관적이어서 좋았던거 같습니다.

책은 요기에서 구매 가능합니다.

Collectors.groupingBy() 메소드는 그룹핑 후 매핑이나 집계(평균,카운팅,연결,최대,최소합계)를 할 수있도록 두번째 매개값으로 Collector를 가질 수 있다.(두번째 매개값으로 인해  기존 value값이 달라진다 ㅎ)

 

 

 

리턴타입 메소드(매개변수) 설명
Collector<T,?,R> mapping(
Function<T,U> mapper
Collector<U,A,R> collector)
T를 U로 매핑후 ,U를 R에 수집
Collector<T,?,Double> averagingDouble(
ToDoubleFunction<T> mapper)
T를 Double로 매핑한후, Double의 평균값을 산출
Collector<T,?,Long> counting() T의 카운팅 수를 산출
Collector<CharSequence,?,String> joining(CharSequence delimier) CharSequence를 구분자(delimiter)로 연결한 String을 산출
Collector<T,?,Optional<T>> maxBy(
Comparator<T> comparator)
Comparator를 이용해서 최대 T를 산출
Collector<T,?,Optional<T>> minBy(
Comparator<T> comparator)
Comparator를 이용해서 최소 T를 산출
Collector<T,?,Integer> summingInt(ToIntFunction)
summingLong(ToLongFunction)
summingDouble(ToDoubleFunction)
Int,Long,Double타입의 합계산출

 

@Data
@AllArgsConstructor
public class Student {

	private String name;
	private int score;
	private Gender gender;
	private City city;
	
	public Student(String name, int score, Gender gender) {
		this.name = name;
		this.score = score;
		this.gender = gender;
	}	
}


public enum  Gender {
     MALE
    , FEMALE
}

public enum City {
    Seoul
    , Pusan
}

 

 

 @Test
    public void groupingAndReductionTest() throws Exception{
        //given
        List<Student> totalList = Arrays.asList(
                new Student("공유", 14, Gender.MALE),
                new Student("김태희", 6, Gender.FEMALE),
                new Student("원빈", 10, Gender.MALE),
                new Student("전지현", 20, Gender.FEMALE)
        );

        Stream<Student> totalStream = totalList.stream();
        Function<Student, Gender> classifier = Student :: getGender;
        ToDoubleFunction<Student> mapper = Student :: getScore;
        Collector<Student, ?, Double> collector1 = Collectors.averagingDouble(mapper);
        Collector<Student, ?, Map<Gender, Double>> collector2 = Collectors.groupingBy(classifier, collector1);
        Map<Gender, Double> mapBySex = totalStream.collect(collector2);

        //성별로 평균 점수를 저장하는 Map 
		Map<Gender, Double> mapByGender = totalList.stream()
				.collect(
					Collectors.groupingBy(
						Student :: getGender,
						Collectors.averagingDouble(Student :: getScore)
					)
				);

        System.out.println("남학생 평균 점수: " + mapBySex.get(Gender.MALE));
        System.out.println("여학생 평균 점: " + mapBySex.get(Gender.FEMALE));


		//성별을 쉼표로 구분한 이름을 저장하는 Map
        Map<Gender, String> mapByName = totalList.stream()
                .collect(
                        Collectors.groupingBy(
                                Student :: getGender,
                                Collectors.mapping(
                                        Student :: getName,
                                        Collectors.joining(",")
                                )
                        )
                );
        System.out.println("남학생 전체 이름: " + mapByName.get(Gender.MALE));
        System.out.println("여학생 전체 이름: " + mapByName.get(Gender.FEMALE));
    }

 

결과

남학생 평균 점수: 12.0
여학생 평균 점: 13.0


남학생 전체 이름: 공유,원빈
여학생 전체 이름: 김태희,전지현

Comments