개발/자바

Map 인터페이스 구현체(HashMap, TreeMap, LinkedHashMap ....)

피터JK 2025. 2. 20. 17:20
728x90

Map 인터페이스는 자바에서 키-값 쌍을 저장하는 컬렉션을 다루기 위한 인터페이스입니다.
Map의 주요 구현체는 다음과 같습니다:

  1. HashMap
  2. TreeMap
  3. LinkedHashMap
  4. Hashtable
  5. ConcurrentHashMap
  6. WeakHashMap
  7. IdentityHashMap

 


1. HashMap

  • 설명: HashMap은 가장 많이 사용되는 Map 구현체로, 해시 테이블을 기반으로 합니다. 키와 값을 해시함수로 처리하여 빠른 검색삽입을 제공합니다. 하지만 순서 보장은 하지 않으며, 키가 같은 경우 덮어쓰기가 발생합니다.
  • 특징:
    • 순서 없음: 키의 순서가 보장되지 않습니다.
    • Null 허용: 하나의 null 키와 여러 개의 null 값을 허용합니다.
    • 성능: 평균적으로 O(1)의 시간 복잡도를 가집니다.
    • 동기화 미지원: 멀티스레딩 환경에서 동기화를 지원하지 않습니다. (synchronized를 사용하거나 별도의 동기화 기법이 필요)
  • 사용 예시:
  import java.util.*;

  public class HashMapExample {
      public static void main(String[] args) {
          Map<String, Integer> map = new HashMap<>();
          map.put("Apple", 10);
          map.put("Banana", 20);
          map.put("Cherry", 30);

          System.out.println(map);  // 순서가 보장되지 않음
      }
  }

2. TreeMap

  • 설명: TreeMap이진 탐색 트리(BST)를 기반으로 구현된 Map으로, 정렬된 키 순서를 보장합니다. 기본적으로 키가 오름차순으로 정렬되며, 내림차순 정렬도 가능합니다.
  • 특징:
    • 정렬된 순서: 키는 항상 정렬된 순서(기본적으로 오름차순)로 저장됩니다.
    • Null 키 금지: null 키는 허용되지 않습니다. 그러나 null 값은 허용됩니다.
    • 성능: 기본적인 put, get, remove 연산은 O(log N)의 시간 복잡도를 가집니다.
    • 범위 조회: headMap, tailMap, subMap 등의 메소드를 통해 범위 조회가 가능합니다.
  • 사용 예시:
  import java.util.*;

  public class TreeMapExample {
      public static void main(String[] args) {
          Map<String, Integer> map = new TreeMap<>();
          map.put("Banana", 3);
          map.put("Apple", 1);
          map.put("Orange", 2);

          System.out.println(map);  // 키가 오름차순으로 정렬됨
      }
  }

3. LinkedHashMap

  • 설명: LinkedHashMapHashMap을 상속받으면서 입력 순서를 보장하는 Map입니다. 내부적으로 링크드 리스트를 사용하여 삽입 순서를 기억합니다.
  • 특징:
    • 입력 순서 보장: 삽입한 순서대로 요소들이 저장되고 순회됩니다.
    • Null 허용: null 키와 null 값을 허용합니다.
    • 성능: HashMap과 비슷하게 평균적으로 O(1)의 시간 복잡도를 가집니다. 그러나 순서 관리로 인해 약간의 오버헤드가 발생합니다.
    • 동기화 미지원: 멀티스레딩 환경에서 동기화를 지원하지 않으며, 별도의 동기화 처리가 필요합니다.
  • 사용 예시:
  import java.util.*;

  public class LinkedHashMapExample {
      public static void main(String[] args) {
          Map<String, Integer> map = new LinkedHashMap<>();
          map.put("Banana", 1);
          map.put("Apple", 2);
          map.put("Orange", 3);

          System.out.println(map);  // 입력 순서대로 출력됨
      }
  }

4. Hashtable

  • 설명: Hashtable구식 Map 구현체로, 동기화가 내장되어 있어 멀티스레딩 환경에서 안전하게 사용할 수 있습니다. 그러나 성능이 떨어지기 때문에 이제는 더 현대적인 HashMap이나 ConcurrentHashMap이 많이 사용됩니다.
  • 특징:
    • 동기화: Hashtable은 기본적으로 스레드 안전합니다.
    • Null 키 및 값 불허: null 키와 null 값은 허용되지 않습니다.
    • 성능 저하: 동기화 처리로 인해 멀티스레딩 환경에서 성능이 떨어집니다.
    • 주로 사용되지 않음: 현재는 HashMap이나 ConcurrentHashMap으로 대체되고 있습니다.
  • 사용 예시:
  import java.util.*;

  public class HashtableExample {
      public static void main(String[] args) {
          Map<String, Integer> map = new Hashtable<>();
          map.put("Banana", 10);
          map.put("Apple", 20);

          System.out.println(map);
      }
  }

5. ConcurrentHashMap

  • 설명: ConcurrentHashMap멀티스레딩 환경에서 스레드 안전Map을 제공합니다. Hashtable의 대안으로 사용되며, 동기화 성능을 개선하기 위해 분할 잠금(Segment Locking) 기법을 사용합니다.
  • 특징:
    • 스레드 안전: 여러 스레드가 동시에 데이터를 읽거나 쓸 수 있도록 지원합니다.
    • 성능: 동기화가 필요한 부분만 잠금 처리하여 성능을 최적화합니다.
    • null 값 불허: null 키와 null 값은 허용되지 않습니다.
    • 분할 잠금: 특정 부분만 잠금하여 병렬성을 최적화합니다.
  • 사용 예시:
  import java.util.concurrent.*;

  public class ConcurrentHashMapExample {
      public static void main(String[] args) {
          Map<String, Integer> map = new ConcurrentHashMap<>();
          map.put("Banana", 5);
          map.put("Apple", 10);

          System.out.println(map);
      }
  }

6. WeakHashMap

  • 설명: WeakHashMap약한 참조(Weak Reference)를 사용하는 Map입니다. 키 객체가 GC(가비지 컬렉션)의 대상이 되면, 해당 키-값 쌍도 자동으로 제거됩니다.
  • 특징:
    • GC 연관: 키 객체가 가비지 컬렉션의 대상이 되면 맵에서 자동으로 제거됩니다.
    • 성능: 메모리 관리가 자동화되어, 메모리 효율성을 개선할 수 있습니다.
    • null 값 허용: null 키와 null 값은 허용되지 않습니다.
  • 사용 예시:
  import java.util.*;

  public class WeakHashMapExample {
      public static void main(String[] args) {
          Map<String, String> map = new WeakHashMap<>();
          map.put("One", "1");
          map.put("Two", "2");

          System.out.println(map);
      }
  }

7. IdentityHashMap

  • 설명: IdentityHashMap== 연산자를 사용하여 객체의 동일성을 비교하는 Map입니다. 기본적으로 HashMapequals() 메소드를 사용하지만, IdentityHashMap객체의 메모리 주소를 기준으로 동일성을 판단합니다.
  • 특징:
    • 객체의 동일성 비교: == 연산자를 사용하여 동일성을 비교합니다.
    • 성능: HashMap에 비해 특정 용도에 맞는 최적화가 이루어집니다.
    • null 값 허용: null 키와 null 값을 허용합니다.
  • 사용 예시:
  import java.util.*;

  public class IdentityHashMapExample {
      public static void main(String[] args) {
          Map<String, String> map = new IdentityHashMap<>();
          map.put(new String("One"), "1");
          map.put(new String("One"), "2");

          System.out.println(map);  // `==`을 사용하므로 다른 객체로 취급됨
      }
  }

결론

각각의 Map 구현체는 사용 목적에 따라 다르게 선택해야 합니다. 예를 들어, 정렬이 필요한 경우 TreeMap, 순서가 중요한 경우 LinkedHashMap, 스레드 안전한 작업이 필요한 경우 ConcurrentHashMap을 사용하는 것이 좋습니다. 각 구현체의 성능과 특징을 잘 이해하고 사용하면, 효율적인 코드를 작성할 수 있습니다.

728x90