[Java8] List를 Map으로 변환 (List to Map)

 

✍️ List to Map

@Getter
@AllArgsConstructor
public class MemberGrade {

    private String name;
    private String subject;
    private int grade;
}

 

1. Simple Loop

List<MemberGrade> memberGrades = new ArrayList<>();

memberGrades.add(new MemberGrade("침착맨", "수학", 100));
memberGrades.add(new MemberGrade("이말년", "수학", 90));
memberGrades.add(new MemberGrade("주호민", "수학", 80));

Map<String, Integer> gradeMap = new HashMap<>();

for (MemberGrade mg : memberGrades) {
    gradeMap.put(mg.getName(), mg.getGrade());
}

System.out.println(gradeMap);
// {침착맨=100, 이말년=90, 주호민=80}

 

2. Java 8 Stream API

List<MemberGrade> memberGrades = new ArrayList<>();

memberGrades.add(new MemberGrade("침착맨", "수학", 100));
memberGrades.add(new MemberGrade("이말년", "수학", 90));
memberGrades.add(new MemberGrade("주호민", "수학", 80));

Map<String, Integer> gradeMap = memberGrades.stream()
        .collect(Collectors.toMap(MemberGrade::getName, MemberGrade::getGrade));

System.out.println(gradeMap);
// {침착맨=100, 이말년=90, 주호민=80}

 

주의할 점으로, Stream API를 사용할 때 중복 키가 있다면 에러가 발생한다.

List<MemberGrade> memberGrades = new ArrayList<>();

memberGrades.add(new MemberGrade("침착맨", "수학", 100));
memberGrades.add(new MemberGrade("침착맨", "국어", 90));
memberGrades.add(new MemberGrade("주호민", "수학", 80));

Map<String, Integer> gradeMap = memberGrades.stream()
        .collect(Collectors.toMap(MemberGrade::getName, MemberGrade::getGrade));

System.out.println(gradeMap);
Exception in thread "main" java.lang.IllegalStateException: Duplicate key 침착맨 (attempted merging values 100 and 99)

 

중복 키가 있을 땐 mergeFunction을 받는 toMap 메서드를 사용하면 된다. 동일한 키값이 있다면 BinaryOperator<U> mergeFunction을 실행한다.

public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                Function<? super T, ? extends U> valueMapper,
                                BinaryOperator<U> mergeFunction) {
    return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
}

 

예를 들어, 이미 Map에 등록된 값을 사용하고 싶다면 아래와 같이 작성할 수 있다.

List<MemberGrade> memberGrades = new ArrayList<>();

memberGrades.add(new MemberGrade("침착맨", "수학", 100));
memberGrades.add(new MemberGrade("침착맨", "국어", 90));
memberGrades.add(new MemberGrade("주호민", "수학", 80));

Map<String, Integer> gradeMap = memberGrades.stream()
        .collect(Collectors.toMap(MemberGrade::getName,
                MemberGrade::getGrade,
                (oldOne, newOne) -> oldOne
        ));

System.out.println(gradeMap);
// {침착맨=100, 주호민=80}

 

혹은 키를 중심으로 값을 누적할 수 있다.

List<MemberGrade> memberGrades = new ArrayList<>();

memberGrades.add(new MemberGrade("침착맨", "수학", 100));
memberGrades.add(new MemberGrade("침착맨", "국어", 90));
memberGrades.add(new MemberGrade("주호민", "수학", 80));

Map<String, Integer> gradeMap = memberGrades.stream()
        .collect(Collectors.toMap(MemberGrade::getName,
                MemberGrade::getGrade,
                Integer::sum
        ));

System.out.println(gradeMap);
// {침착맨=190, 주호민=80}

 

🌱  관련

[Java8] List를 Map으로 변환 (List to Map)

[Java8] List를 Set으로 변환 (List to Set)

[Java8] Set을 List로 변환 (Set to List)

[Java8] Set을 Map으로 변환 (Set to Map)

[Java8] Map을 List로 변환 (Map to List)

[Java8] Map을 Set으로 변환 (Map to Set)