본문 바로가기

Spring & Java

Java Object Stream group by multiple field and map in map to list

반응형

java stream 을 사용하여 객체 리스트를 여러개 필드로 그룹핑 후 맵형태로 생성 후 리스트로 출력 해보도록 한다.

  • 원본 리스트를 그룹핑 하여 출력되는 최종 결과는 아래 그림과 같다.

    List<Course> courseList = Arrays.asList(
                Course.builder()
                        .code("A0001")
                        .subject("Math")
                        .semester("First")
                        .price(10000l)
                        .build(),
                Course.builder()
                        .code("A0001")
                        .subject("Math")
                        .semester("Second")
                        .price(10000l)
                        .build(),
                Course.builder()
                        .code("A0005")
                        .subject("OperatingSystem")
                        .semester("Second")
                        .price(10000l)
                        .build(),
                Course.builder()
                        .code("A0005")
                        .subject("OperatingSystem")
                        .semester("Second")
                        .price(10000l)
                        .build(),
                Course.builder()
                        .code("A0003")
                        .subject("DataScience")
                        .semester("Second")
                        .price(10000l)
                        .build()
        );
    
        List<Course> resultList = courseList.stream()
                //groupby code and subject
                //output-> Map<String,Map<String,List<Course>>>
                .collect(groupingBy(Course::getCode, groupingBy(Course::getSubject)))
                .entrySet()
                //output -> Set<Map<K,V>.Entry<String,Map<String,List<Course>>>>
                .stream()
                //output -> Stream<Map<K,V>.Entry<String,Map<String,List<Course>>>>
                .map(h -> h.getValue()
                        //output -> Map<String,List<Course>> 
                        .entrySet()
                        //output -> Set<Map<K,V>.Entry<String,List<Course>>>
                        .stream()
                        //output -> Stream<Map<K,V>.Entry<String,List<Course>>>
                        .map(m -> m.getValue()
                                .stream()
                                .reduce((c1, c2) -> Course.builder()
                                        .code(c1.getCode())
                                        .semester(c1.getSemester())
                                        .subject(c1.getSubject())
                                        .price(c1.getPrice() + c2.getPrice())
                                        .build()))
                        //output -> Stream<Optional<Course>>
                        .map(z -> z.get())
                        //output -> Stream<Course>
                        .collect(Collectors.toList()))
                //output -> Stream<List<Course>>
                .collect(Collectors.toList())
                //output -> List<List<Course>>
                .stream()
                //output -> Stream<List<Course>>
                .flatMap(x -> x.stream())
                //output -> Stream<Course>
                .collect(Collectors.toList());
반응형