29

私はEnumMapオーバーを使用することの長所と短所を比較検討しようとしていHashMapます。私はいつもを使って調べているので、キー付きのaが正しい選択Stringだと思われます。ただし、キーを特定の列挙に制限するという私の意図を伝えるため、より良い設計のように思えます。考え?HashMapStringEnumMap

これは、私がどのように使用するかを示す、作り話の例ですMap

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を使うべきですか?

4

4 に答える 4

13

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

文字列はさまざまな用途に使用でき、「動物」の文字列を他の用途に使用する文字列に簡単に変換できるため、混乱を避けることもできます。列挙型は一般に他の型と交換できないため(共通のインターフェイスを使用しない限り)、コーディングでエラーが発生する可能性は低くなります。

于 2012-05-04T08:27:42.797 に答える
3

可能なキーのセットが有限であり、事前にわかっている場合(例/質問が示唆しているように)、列挙型はこれを完全に表しています。他に述べたように、列挙型を使用すると、キーの使用に間違いがないことが保証されます。

さらに、キーの範囲が事前にわかっているため、このMapの実装は非常に最適化されています(私が知る限り、EnumMapは内部で長さnumberOfEnumsの配列を使用、列挙型の序数でインデックス付けされます)。

だから私もお勧めしEnumMapます。

ただし、覚えておくべき2つの(小さな)こと:

  • 継承によって特殊なケースを追加することはできません(列挙型を拡張できないため、たとえば、側面に特殊な哺乳類のマップがある動物のマップはありません)
  • 列挙型にメンバーを追加するときに、他のメンバーの「途中」にメンバーを追加すると、序数が変更されます。この情報はEnumMapで使用できるため、古いバージョンの列挙型から構築されたEnumMapをリロードすると(たとえば、シリアル化を使用して)、問題が発生する可能性があります。
于 2012-05-04T09:12:45.097 に答える
0

Key Of Mapは変更不可能で一意である必要があり、これはEnumを使用して保証できます。

また、Stringの管理に比べて、管理が簡単でエラーが発生しにくくなります。

だから、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;
  }

}
于 2012-05-04T08:29:49.167 に答える
0

まず第一に、すべてのキーは最終的に不変です。あなたは間違いなくを使用する必要がありますEnumMap

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

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

:font_sizeはRubyのシンボルであり、Javaの最後の静的な対応物です。

于 2013-07-02T13:16:30.037 に答える