java / / 2023. 9. 10. 19:40

stream의 toMap에서 Function.identity() 사용

일반적으로 Stream을 사용할 때 map으로 변환하기 위해 Collectors.toMap을 사용한다.

예를 들어 아래의 코드가 있다고 해보자

public class User {
    private String id;
    private String name;
}

List<User> users = Arrays.asList(
        new User("hong", "홍길동"),
        new User("lee", "이승엽"),
        new User("kim", "김기동")
);

toMap의 기본 사용법

users List를 id와 name을 가진 map으로 변환을 하려면 아래와 같이하면 된다.

Map<Integer, String> userMap = users.stream()
  .collect(Collectors.toMap(User::getId, User::getName));
System.out.println(userMap); // {hong=홍길동, lee=이승엽, kim=김기동}
System.out.println(userMap.get("hong")); // 홍길동

Function.identity() 사용법

하지만 map의 value에 name이 아닌 User 객체를 넣고 싶을 경우에는 어떻게 해야 할까?

Function.identity()를 사용하면 된다.

Map<String, User> userMap2 = users.stream()
  .collect(Collectors.toMap(User::getId, Function.identity()));
System.out.println(userMap2); // {hong=FunctionSample.User(id=hong, name=홍길동), lee=FunctionSample.User(id=lee, name=이승엽), kim=FunctionSample.User(id=kim, name=김기동)}
System.out.println(userMap2.get("hong")); // FunctionSample.User(id=1, name=홍길동)
System.out.println(userMap2.get("hong").getName()); // 홍길동

키 중복이 생기는 경우

만일 id의 길이로 toMap을 하면 어떻게 될까?

4=홍길동, 3=이승엽, 3=김기동으로 표시될 것 같은데 한번 실행해보자.

Map<Integer, User> userMap = users.stream()
        .collect(Collectors.toMap(
                user -> user.getId().length(),
                Function.identity()
        ));
System.out.println(userMap);

실행하면 아래와 같은 오류가 발생한다.

Exception in thread "main" java.lang.IllegalStateException: Duplicate key FunctionSample.User(id=lee, name=이승엽)

키 중복 해결법

toMap 시 중복키에 대한 오류를 방지하기 위한 해결책도 이미 가지고 있다.

Map<Integer, User> userMap = users.stream()
        .collect(Collectors.toMap(
                user -> user.getId().length(),
                Function.identity(),
              (oldValue, newValue) -> oldValue) // 기존값, 새로운 값 중 선택을 할 수 있다.
        );
System.out.println(userMap);

위에서 (oldValue, newValue)으로 기존값이나 새로운값으로 선택을 할 수 있는 옵션이 있다. 여기서는 기존값(oldValue)로 선택을 했다.

이렇게 실행하면 아래와 같은 결과가 표시된다.

{3=FunctionSample.User(id=lee, name=이승엽), 4=FunctionSample.User(id=hong, name=홍길동)}

이승엽(기본값), 김기동(새로운 값) 중 이승엽으로 출력이 된다.

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유