본문 바로가기

자바 멀티스레딩, 병행성 및 성능최적화

Map 불변성과 순서를 보장하고싶을 때 어떻게 해야할까

728x90

이 이야기는 Java에서 Map과 Set 같은 컬렉션의 순서 보장불변성(immutable) 유지에 관한 것입니다. 코드를 작성할 때, 특정 순서를 유지하고 불변성을 지켜야 하는 경우가 많습니다. 이때 Java의 Map.copyOf와 Collections.unmodifiableMap 등의 메서드가 어떻게 작동하는지를 잘 이해해야 문제가 생기지 않죠. 핵심 부분을 간단히 정리해볼게요.

  1. Map과 순서 보장 문제
    일반적으로 Java에서 HashMap과 Set은 넣은 순서를 보장하지 않아요. 예를 들어, 1, 2, 3 순서로 넣어도 3, 1, 2 순서로 출력될 수도 있죠. 순서가 중요한 경우 LinkedHashMap이나 LinkedHashSet을 사용하면 됩니다. 이들은 넣은 순서를 그대로 유지해주죠.
  2. Map.copyOf 사용 시 문제 발생
    Map.copyOf 메서드는 불변의 Map을 반환해주는 편리한 방법이지만, 순서를 보장하지 않는 ImmutableCollections.MapN 타입으로 반환해요. 즉, LinkedHashMap이 들어가도 그 성질(순서 보장)이 유지되지 않습니다. 따라서 순서가 중요할 때 Map.copyOf를 사용하면 안 됩니다.
  3. 해결 방법: Collections.unmodifiableMap
    순서를 유지하면서 불변성을 가지려면, Collections.unmodifiableMap 메서드를 사용해 직접 LinkedHashMap의 복사본을 생성하고, 그 복사본을 수정 불가하도록 만드는 방법이 있습니다.이 코드는 LinkedHashMap의 순서를 유지하면서 불변성을 지키는 방법입니다.
  4. java
    코드 복사
    Map<String, Integer> testMap = new LinkedHashMap<>();
    return Collections.unmodifiableMap(new LinkedHashMap<>(testMap));
  5. Collections.unmodifiableMap의 내부 동작 원리
    Collections.unmodifiableMap은 UnmodifiableMap이라는 내부 클래스를 반환합니다. 이 클래스는 생성자에서 받아온 Map의 참조를 유지하면서, 그 Map의 원래 성질(순서 보장 등)을 그대로 갖고 있어요. UnmodifiableMap은 내부적으로 원래의 Map에 대한 참조를 그대로 가지고 그 Map을 수정하지 못하도록 put, remove 같은 수정 메서드들은 오버라이드해서 막아버립니다.
  6. Map이 아닌 다른 컬렉션에도 동일하게 적용
    이 개념은 Set과 같은 다른 컬렉션에서도 동일하게 적용됩니다. 따라서 순서를 유지하면서 불변성을 유지하려면 Set.copyOf 대신 Collections.unmodifiableSet(new LinkedHashSet<>(set))과 같은 방식으로 사용해야 합니다.

이처럼, 순서 보장과 불변성 유지가 동시에 필요할 때는 Map.copyOf 대신 Collections.unmodifiableMap을 사용하는 것이 중요합니다.

 


unmodifiableList()

List.of()

추가 Java 1.2 Java 9
원본 복사x 복사o
사용 방법 목표컬렉션.stream().collect(Collectors.toUnmodifiableList()); List.of(목표 요소, 목표 요소,...)

 

 

결론:  Map에서 순서를 보장과 불변성을 띄고싶다면 unmodifiableList을 사용하자 Map.Copyof는 순서를 보장하지못한다.

because  ImmutableCollections.MapN 타입으로 반환하기 때문

 

728x90