56 votes

La longueur des valeurs énumérées () par rapport au champ privé

J'ai une énumération comme ceci :

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; }
}

Parfois, j'ai besoin de vérifier combien de champs j'ai dans l'énumération. Quelle est la meilleure solution? Devrais-je utiliser une méthode "values().length"? Ou peut-être, dois-je créer un champ constant dans l'énumération comme ceci :

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;
}

Quelle est la solution la plus rapide et la plus élégante ?

105voto

Jon Skeet Points 692016

En utilisant values().length, vous créerez une nouvelle copie du tableau à chaque appel. Parfois, je crée ma propre List (ou ensemble, ou carte, selon mes besoins) pour éviter cette copie inutile. Je ne le coderais pas en dur cependant... si vous avez seulement besoin de la taille, j'utiliserais simplement :

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

à la fin. Au moment où cela est évalué, toutes les valeurs auront été initialisées. Cela évite les préoccupations de DRY et d'incohérence soulevées dans d'autres réponses.

Bien sûr, il s'agit d'une forme de micro-optimisation en soi... mais qui se termine par un code plus simple à la fin, selon moi. Appeler values().length d'ailleurs ne montre pas vraiment ce qui vous intéresse, qui est juste la taille de l'énumération - le fait que vous y accédiez via un tableau de valeurs est incident et distrayant, selon moi.

Une alternative à l'utilisation de values() est d'utiliser EnumSet.allOf().size() qui pour les petites énumérations sera assez bon marché - mais encore une fois, ce n'est pas aussi lisible que d'avoir simplement un champ size.

1 votes

Si vous voulez respecter les conventions de nommage Java, ne devriez-vous pas nommer cette constante SIZE plutôt que size?

0 votes

@Jubobs : Je le ferais certainement pour une constante publique, mais pour une constante privée, ça m'importe peu de toute façon. Notez que ce n'est pas une constante au moment de la compilation.

0 votes

Merci d'avoir expliqué votre raisonnement.

9voto

Adamski Points 29884

Je recommanderais d'utiliser values().length. C'est beaucoup plus élégant et le surcoût en termes de performance par rapport à l'utilisation d'une constante sera négligeable. De plus, vous éliminez le risque que la constante devienne jamais décalée par rapport à la longueur réelle de l'énumération.

8voto

PaulJWilliams Points 11641

En stockant le compteur, vous violez le principe DRY, donc à moins d'avoir une très bonne raison, vous ne devriez pas le faire.

0 votes

Aaarrgghh - Je cherchais désespérément sur Google pour cela mais j'ai oublié comment ça s'appelait!

6voto

Une autre approche est d'utiliser une constante initialisée en haut de la méthode values().

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

De cette façon, vous disposez d'une constante automatiquement mise à jour et évitez toujours les frais généraux de "values()".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X