it-swarm-ja.tech

Enum values()。length vs private field

私はこのような列挙を持っています:

public enum Configuration {
    XML(1),
    XSLT(10),
    TXT(100),
    HTML(2),
    DB(20);

    private final int id;
    private Configuration(int id) {
        this.id = id;
    }
    public int getId() { return id; }
}

時々、列挙にあるフィールドの数を確認する必要があります。最善の解決策は何ですか?メソッド「values()。length」を使用する必要がありますか?または、次のような列挙型の定数フィールドを作成する必要があります。

public enum Configuration {
    XML(1),
    XSLT(10),
    TXT(100),
    HTML(2),
    DB(20);

    private final int id;
    private Configuration(int id) {
        this.id = id;
    }
    public int getId() { return id; }

    public static final int Size = 5;
}

最も高速でエレガントなソリューションは何ですか?

54
Michał Ziober

values().lengthを使用すると、呼び出すたびに配列の新しいコピーが作成されます。この無意味なコピーを避けるために、自分でList(または必要に応じてセットまたはマップ)を作成することがあります。 I would n'tしかし、それをハードコーディングします...サイズだけが必要な場合、私はただ使用します:

_private static final int size = Configuration.values().length;
_

最後に。評価されるまでに、すべての値が初期化されています。これにより、DRYおよび他の回答で生じる不一致の懸念が回避されます。

もちろん、これはそれ自体が少し最適化されています...しかし、最終的にsimpler codeで終わるもの、IMOです。他の場所からvalues().lengthを呼び出しても、興味のあることは表明されません。これはjust enumのサイズです。値の配列から取得するという事実は偶発的で注意散漫なIMO。

values()を使用する代わりにEnumSet.allOf().size()を使用することもできます。これは、小さな列挙型ではかなり安価になりますが、sizeフィールドがあるほど読みやすくはありません。

100
Jon Skeet

values().lengthを使用することをお勧めします。これははるかにエレガントで、定数を使用する場合と比べてパフォーマンスのオーバーヘッドは無視できます。また、列挙の実際の長さと定数がずれることのリスクを排除します。

9
Adamski

カウントを保存することで、 DRY原則 に違反しているので、非常に正当な理由がない限り、そうすべきではありません。

8
PaulJWilliams

別のアプローチは、values()メソッドの上で初期化された定数を使用することです。

public enum Colors {
    BLUE, GREEN, Fuchsia;
    public static int COUNT = Colors.values().length;
}

このようにして、定数が自動的に更新され、「values()」のオーバーヘッドを回避できます。