2009-07-29 9 views
5

私たちのプロジェクトのいたるところに、この種の列挙型があります。彼らはうまく動作しますが、私たちはそれらについては分かりません。は私の列挙は正しいですか?

特にgetDocumentType(String)メソッドを使用しています。

すべてのEnumsフィールドで反復を避ける方法はありますか?

public enum DocumentType { 

    UNKNOWN("Unknown"), 
    ANY("Any"), 
    ASSET(Asset.class.getSimpleName()), 
    MEDIA(Media.class.getSimpleName()), 
    MEDIA35MM(Media.class.getSimpleName() + " 35mm"); 


    private String label; 

    private DocumentType(String label) { 
     this.label = label; 
    } 

    public String getLabel() { 
     return label; 
    } 

    public static DocumentType getDocumentType(String label){ 
     for(DocumentType documentType : DocumentType.values()){ 
      if(documentType.getLabel().equals(label)){ 
       return documentType; 
      } 
     } 
     return UNKNOWN; 
    } 
} 

編集: newacctレスポンスを確認してください。彼女も大丈夫です。

+1

静的なラベルのマップを列挙型インスタンスに格納するのは魅力的ですが、残念ながら、javaでは列挙型のコンストラクタから静的フィールドを参照させることはできません。 – skaffman

+1

"Asset"を書くのではなく、なぜAsset.class.getSimpleName()を使用するのだろうか?リファクタリングで名前を変更する予定ですか? – akarnokd

+1

文字列ではなくクラスリテラルを使用することは常に良い習慣なので、 – skaffman

答えて

5

enumを書く際の制限のため、どこかでその反復処理を行う必要があります。理想的な世界では、DocumentTypeのコンストラクタ内から静的Mapを作成しますが、これは許可されていません。

私が提案できる最善のは、静的初期化子で一回の繰り返しを実行し、ルックアップテーブルに列挙型を記憶している。

public enum DocumentType { 

    .... existing enum stuff here 

    private static final Map<String, DocumentType> typesByLabel = new HashMap<String, DocumentType>(); 
    static { 
     for(DocumentType documentType : DocumentType.values()){ 
      typesByLabel.put(documentType.label, documentType); 
     } 
    } 

    public static DocumentType getDocumentType(String label){ 
     if (typesByLabel.containsKey(label)) { 
      return typesByLabel.get(label); 
     } else { 
      return UNKNOWN; 
     } 
    } 
} 

は、少なくとも、あなたは私が、毎回の繰り返しをしていることはありません意味のあるパフォーマンスの改善が見えるのではないかと疑います。

+0

+1私が考えていたことは、あなたが私を打ち負かした=) – mikek

+1

私はちょうど10分ほどコンパイラで叫んでいました – skaffman

+0

enumに要素が100個(またはさらに千)ある場合は、これがパフォーマンスの向上になるかもしれません...おそらくあなたがこれらをたくさん見ているかもしれません。 – aperkins

1

私が知っている限りでは(それが価値があるのに対して)、それはあなたが望むことをする最善の方法です。

これは私が少なくともそれをやる方法です。

あなたenum数が大幅に大きくなった場合(数百 - 数千人)あなたが少し速くルックアップを行うためにenumsStringsMap INGを追加することもできます。しかし、あなたが持っているeunumsの少量のために、これは過度の可能性があります。

1

私にはうまく見えます。

私はそのまま繰り返します。もちろん、マップ< 'label'、 'DocumentType'>の実装を列挙型クラスに追加して検索することはできますが、パフォーマンスが大幅に向上することはありません。

1

文字列はコンパイル時に知られており、それらが有効な識別子であれば、あなただけの直接列挙型の名前としてそれらを使用することができる場合:

public enum DocumentType { Unknown, Any, Asset, Media, Media35mm } 

、その後.valueOf()でそれを得ます。例:

String label = "Asset"; 
DocumentType doctype; 
try { 
    doctype = DocumentType.valueOf(label); 
} catch (IllegalArgumentException e) { 
    doctype = DocumentType.Unknown; 
} 
+0

同僚が同じ解決策を検討していました。私たちの正確なケースではなく、ほとんどの場合、大丈夫ですが、次回の反復では、本当に識別子とラベルを除外しているかどうかを確認します。 –

関連する問題