2012-05-04 7 views
27

을 통해 EnumMap을 사용하는 장단점을 비교하려고합니다. 이후로 항상 String을 사용하여 찾고있을 것이므로 String 키를 가진 HashMap이 올바른 선택 인 것으로 보입니다. 그러나 EnumMap은 키를 특정 열거로 제한하려는 나의 의도를 전달하기 때문에 더 나은 디자인처럼 보입니다. 생각? 조회 키가 문자열 인 경우 EnumMap 또는 HashMap

enum AnimalType { CAT, DOG } 
interface Animal {} 
class Cat implements Animal {} 
class Dog implements Animal {} 

public class AnimalFactory { 

    private static final Map<AnimalType, Animal> enumMap 
      = new EnumMap<AnimalType, Animal>(AnimalType.class); 
    // versus 
    private static final Map<String, Animal> stringMap 
      = new HashMap<String, Animal>(); 

    static { 
     enumMap.put(AnimalType.CAT, new Cat()); 
     enumMap.put(AnimalType.DOG, new Dog()); 
     stringMap.put("CAT", new Cat()); 
     stringMap.put("DOG", new Dog()); 
    } 
    public static Animal create(String type) { 
     Animal result = enumMap.get(AnimalType.valueOf(type)); 
     Animal result2 = stringMap.get(type); 
     return result; 
    } 
} 

AnimalType 열거 및지도 만 다른 곳에서는 동물을 만들 수 AnimalFactory에 의해 사용된다는 것을 가정 : 여기

내가 Map를 사용하는 방법을 보여주는 메이크업 믿고 예입니다.

어떤 Map을 사용해야합니까?

+0

@dogbane 어떤 진행 상황입니까? – Javanator

답변

12

모든 유효한 키를 열거 할 수 있다면 항상 올바른 값으로 작업 할 수 있으므로이 키를 사용합니다.

String을 많은 것들에 사용할 수 있고 "Animal"문자열을 다른 것으로 사용되는 문자열로 바꾸기 쉽기 때문에 혼동을 피할 수도 있습니다. enum 유형은 일반적으로 다른 유형과 교환 할 수 없으므로 (공용 인터페이스를 사용하지 않는 한) 코딩시 오류가 적습니다.

+0

동물 열거 형 및지도는 동물을 만들기 위해 AnimalFactory에서만 사용되며 다른 곳에서는 사용하지 마십시오. 여전히 EnumMap이 더 좋다고 생각하십니까? EnumMap을 사용할 때 조회 전에 문자열을 열거 형으로 변환하는 비용에 대해 어떻게 생각합니까? – dogbane

+1

지도 자체에서 문자열을 찾는 비용과 거의 같습니다. EnumMap에는 배열에 대한 래퍼가 두 배로 늘지 않습니다. ;) –

0

키 맵은 수정할 수 없어야하며 고유해야하며 Enum을 사용하여 보장 할 수 있습니다.

String을 관리하는 것보다 관리가 더 쉽고 오류가 발생하기 쉽습니다.

그래서 이동하십시오. EnumMap.

또한 고급 enum이 있으므로 키와 함께 많은 정보와 작업을 추가 할 수 있습니다.

enum AnimalType { 

    Dog("I am dog and I hate cats", true), 
    CAT("I am cat and I love to eat rats", true), 
    RAT("I am a mouse and I love tearing human cloths apart", false) ; 

    private final String description; 
    private final boolean isHelpFullToHuman; 

    private AnimalType(String description , boolean isHelpFullToHuman) { 
    this.description = description; 
    this.isHelpFullToHuman = isHelpFullToHuman; 
    } 

    public boolean isHelpFullToHuman() { 
    return isHelpFullToHuman; 
    } 

    public String getDescription() { 
    return description; 
    } 

} 
+0

"오류가 발생하기 쉬운"이유가 무엇입니까? – dogbane

+0

나열된 키가 열거 형의 경우 허용되지 않으며 일부 클래스의 상수는 상수 일 수 있습니다. 내 의견에 오류가 발생하기 쉬운 단어는 중앙 집중식 요소가 아니지만 :) – Javanator

3

가능한 키 집합이 유한하고 미리 알 수 있다면 (예제/질문에서 제안하는 것처럼) 열거 형은이를 완벽하게 나타냅니다. 다른 말처럼 enum의 사용은 키의 사용에 실수가 없음을 보장합니다. 키의 범위가 사전에 알려진 바와

또,지도의 구현이 매우 최적화된다 (최대한 멀리 knwow 같이 EnumMap는 길이의 배열을 이용 numberOfEnums 내부적 ENUM의 순서에 의해 인덱싱).

나는 또한 EnumMap을 추천합니다.

두 (작은) 일하지만 유의해야 할 사항은 다음과 같습니다

  • 당신이 상속에 의해 특별한 경우를 추가 할 수 없습니다 (당신은 포유류의 전문지도로, 동물의 그래서지도를 열거을 확장 할 수 없습니다 예를 들어 측면에)
  • 열거 형에 멤버를 추가 할 때 다른 멤버의 "중간에"추가하면 서수를 변경할 수 있습니다. 이 정보는 EnumMap에서 사용할 수 있으므로 EnumMap을 이전 버전의 열거 형에서 다시로드하면 문제가 될 수 있습니다 (예 : 직렬화 사용)
+0

당신이 말한 것처럼 EnumMap '는 빠르지 만 조회를 수행하기 전에 입력 문자열을 열거 형으로 변환하는 추가 비용이 있습니다. – dogbane

0

우선 모든 키는 최종 변경 불가능합니다. 반드시 EnumMap을 사용해야합니다.

이 루비에 해시 같다 :

options = { :font_size => 10, :font_family => "Arial" } 

:font_size 루비의 상징, 자바의 최종 정적 대응이다.