728x90
이 이야기는 Java에서 Map과 Set 같은 컬렉션의 순서 보장과 불변성(immutable) 유지에 관한 것입니다. 코드를 작성할 때, 특정 순서를 유지하고 불변성을 지켜야 하는 경우가 많습니다. 이때 Java의 Map.copyOf와 Collections.unmodifiableMap 등의 메서드가 어떻게 작동하는지를 잘 이해해야 문제가 생기지 않죠. 핵심 부분을 간단히 정리해볼게요.
- Map과 순서 보장 문제
일반적으로 Java에서 HashMap과 Set은 넣은 순서를 보장하지 않아요. 예를 들어, 1, 2, 3 순서로 넣어도 3, 1, 2 순서로 출력될 수도 있죠. 순서가 중요한 경우 LinkedHashMap이나 LinkedHashSet을 사용하면 됩니다. 이들은 넣은 순서를 그대로 유지해주죠. - Map.copyOf 사용 시 문제 발생
Map.copyOf 메서드는 불변의 Map을 반환해주는 편리한 방법이지만, 순서를 보장하지 않는 ImmutableCollections.MapN 타입으로 반환해요. 즉, LinkedHashMap이 들어가도 그 성질(순서 보장)이 유지되지 않습니다. 따라서 순서가 중요할 때 Map.copyOf를 사용하면 안 됩니다. - 해결 방법: Collections.unmodifiableMap
순서를 유지하면서 불변성을 가지려면, Collections.unmodifiableMap 메서드를 사용해 직접 LinkedHashMap의 복사본을 생성하고, 그 복사본을 수정 불가하도록 만드는 방법이 있습니다.이 코드는 LinkedHashMap의 순서를 유지하면서 불변성을 지키는 방법입니다. -
java코드 복사Map<String, Integer> testMap = new LinkedHashMap<>();return Collections.unmodifiableMap(new LinkedHashMap<>(testMap));
- Collections.unmodifiableMap의 내부 동작 원리
Collections.unmodifiableMap은 UnmodifiableMap이라는 내부 클래스를 반환합니다. 이 클래스는 생성자에서 받아온 Map의 참조를 유지하면서, 그 Map의 원래 성질(순서 보장 등)을 그대로 갖고 있어요. UnmodifiableMap은 내부적으로 원래의 Map에 대한 참조를 그대로 가지고 그 Map을 수정하지 못하도록 put, remove 같은 수정 메서드들은 오버라이드해서 막아버립니다. - Map이 아닌 다른 컬렉션에도 동일하게 적용
이 개념은 Set과 같은 다른 컬렉션에서도 동일하게 적용됩니다. 따라서 순서를 유지하면서 불변성을 유지하려면 Set.copyOf 대신 Collections.unmodifiableSet(new LinkedHashSet<>(set))과 같은 방식으로 사용해야 합니다.
이처럼, 순서 보장과 불변성 유지가 동시에 필요할 때는 Map.copyOf 대신 Collections.unmodifiableMap을 사용하는 것이 중요합니다.
|
List.of() |
|
추가 | Java 1.2 | Java 9 |
원본 | 복사x | 복사o |
사용 방법 | 목표컬렉션.stream().collect(Collectors.toUnmodifiableList()); | List.of(목표 요소, 목표 요소,...) |
결론: Map에서 순서를 보장과 불변성을 띄고싶다면 unmodifiableList을 사용하자 Map.Copyof는 순서를 보장하지못한다.
because ImmutableCollections.MapN 타입으로 반환하기 때문
728x90