2012-05-04 3 views
27

を超えるEnumMapを使用することの長所と短所を比較しようとしています。私は常に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列挙型とマップがONLYどこにも動物を作成するために AnimalFactoryによって使用されることを想定します。ここでは

は私が Mapを使用する方法を示し、メイク信じる例です。

どれがMapを使用しますか?

+0

@dogbane – Javanator

答えて

12

すべての有効なキーを列挙できる場合は、常に有効な値で作業していることを確認するために使用します。

Stringは多くのものに使用でき、 "Animal"文字列を他のものに使用される文字列に変換するのは簡単です。列挙型は(一般的なインターフェイスを使用しない限り)一般的に他の型と互換性がないため、コーディングでエラーが発生する可能性は低くなります。

+0

動物列挙とマップは、動物を作成するためにAnimalFactoryによってのみ使用され、それ以外はどこでも、EnumMapが優れていると思われますか? EnumMapを使用するときに検索の前に文字列を列挙型に変換するコストについてどう思いますか? – dogbane

+1

マップ自体の文字列を検索するコストとほぼ同じです。 EnumMapには配列のラッパーとして効果的な倍増はありません。 ;) –

0

マップのキーは変更不可能でUniqueであり、これはEnumを使用して保証することができます。

また、管理することは、文字列を管理するのと比較して、より簡単で、エラーの発生が少なくなります。

だから移動EnumMap。

私たちは高度な列挙型を持っているので、他の多くの情報や操作をキー自体に付けることができます。

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もお勧めします。

二けれども心に留めておくべき(少し)のもの:

  • あなたは(あなたが列挙型を拡張することはできません継承によって、特殊なケースを追加することはできませんので、哺乳類の専門マップでANIMALSのない地図はありません
  • メンバーを列挙型に追加するときに、他のメンバーの「真ん中に」追加すると、序数が変更されます。この情報はEnumMapで使用できるため、EnumMapを古いバージョンのenumから再ロードすると問題が発生する可能性があります(例えばシリアライゼーションを使用して)
+0

あなたが言うように、 'EnumMap 'は高速ですが、ルックアップを実行する前に入力文字列を列挙型に変換する追加コストがあります。 – dogbane

0

まず、すべてのキーは最終変更不可能です。間違いなくEnumMapを使用する必要があります。

これはRubyでハッシュのようなものです:

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

:font_sizeは、Ruby、Javaで最終静的対応でシンボルです。

関連する問題