IT/Java

HashMap, HashSet 과 EnumMap, EnumSet과의 차이점

yeTi 2022. 6. 8. 18:49

안녕하세요. yeTi입니다.
오늘은 백기선님의 강의 중 자바의 열거 타입를 보다가 받은 숙제인 HashMap, HashSet과 EnumMap, EnumSet과의 차이점 확인해보고자 합니다.

EnumSet의 구조

EnumSet 은 내부적으로 bit vector를 사용하기 때문에 메모리 효율이나 성능면에서 뛰어나고 64bit를 넘어가는 경우도 대응할 수 있습니다.
다만 thread-safe 하지 않기 때문에 multi-thread 환경에서 사용하려면 Collections.synchronizedSet() 을 사용하여야 합니다.

따라서 Bit 필드 사용해야될 경우 EnumSet 을 사용하면 효율이나 성능측면에서 득이 됩니다.

public class Text {
  public enum Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH }
  public void applyStyles(Set<Style> styles) { ... }
}

...

text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC);

EnumMap의 구조

EnumMap 은 내부적으로 배열로 관리합니다. 키를 별도로 관리하지 않음으로써 메모리를 좀더 효율적으로 사용할 수 있고, value 검색시 즉시 데이터의 위치값을 알 수 있어 효율적인 구조를 가질 수 있습니다.

public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>  
    implements java.io.Serializable, Cloneable  
{
...
  private transient Object[] vals;
...
}

따라서 get() 을 요청하면 Enumordinal 을 인덱스로 활용하여 value 를 조회하도록 되어있습니다.

public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>  
    implements java.io.Serializable, Cloneable  
{
...
  public V get(Object key) {  
    return (isValidKey(key) ?  
            unmaskNull(vals[((Enum<?>)key).ordinal()]) : null);  
  }
...
}

HashSet의 구조

HashSet 은 내부적으로 HashMap 에 데이터를 적재합니다.

public class HashSet<E>  
    extends AbstractSet<E>  
    implements Set<E>, Cloneable, java.io.Serializable  
{
...
  private transient HashMap<E,Object> map;
...
}

HashMap의 특성이 중복값을 허용하지 않는 것을 아이디어로 해서 키에 데이터를 저장하여 유니크한 데이터만 저장하도록 구현되어있습니다.

이 때, Map 자료구조 특성상 value 가 필요한 부분은 PRESENT 라는 더미 데이터로 채워 넣는것이 특징입니다.

public class HashSet<E>  
    extends AbstractSet<E>  
    implements Set<E>, Cloneable, java.io.Serializable  
{
...
  public boolean add(E e) {  
    return map.put(e, PRESENT)==null;  
  }
...
}

HashMap의 구조

HashMaphash table 기반 Map 자료구조를 가지는 클래스입니다. hash 는 입력된 keyhashCode 를 활용하여 생성하고, TreeNode 를 활용하여 트리 자료구조로 데이터를 가집니다.

결론

Hash기반 collection과 Enum기반 collection은 해당 데이터 타입의 특징에 맞게 자료구조를 구현한 특징을 가지고 있습니다.

Hash 의 경우는 Hash code 를 키로하여 트리 구조로 데이터를 적재하는 특징을 가지는 반면

Enum 의 경우 ordinal 값이 존재하는것을 활용하여 리스트로 데이터를 적재 후 인덱스값으로 직접 접근하는 특징을 가지는것을 확인할 수 있습니다.