56 votes

Enum values().length vs 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; }
}

J'ai parfois besoin de vérifier combien de champs j'ai dans l'énumération. Quelle est la meilleure solution ? Dois-je utiliser une méthode "values().length" ? Ou peut-être, je dois 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

Utilisation de values().length créera une nouvelle copie du tableau à chaque fois que vous l'appellerez. Je crée parfois mes propres List (ou ensemble, ou carte, selon mes besoins) pour éviter cette copie inutile. I ne serait pas si vous n'avez besoin que de la taille, j'utiliserais simplement :

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

à la fin. Au moment de l'évaluation, toutes les valeurs auront été initialisées. Cela évite les problèmes de DRY et d'incohérence soulevés dans d'autres réponses.

Bien sûr, il s'agit là d'une micro-optimisation en soi... mais qui se traduit par plus simple code à la fin, IMO. Appeler values().length d'ailleurs n'exprime pas ce qui vous intéresse, c'est-à-dire juste la taille de l'enum - le fait que vous y accédiez par un tableau de valeurs est accessoire et distrayant, IMO.

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

1 votes

Si vous voulez adhérer aux conventions de nommage de 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 ne me dérange pas trop non plus. Notez que ce n'est pas un temps de compilation constant.

0 votes

Merci d'avoir expliqué votre raisonnement.

9voto

Adamski Points 29884

Je recommande d'utiliser values().length . C'est beaucoup plus élégant et le surcoût de performance par rapport à l'utilisation d'une constante sera négligeable. En outre, vous éliminez le risque que la constante ne soit pas en phase avec la longueur réelle de l'énumération.

8voto

PaulJWilliams Points 11641

En stockant le compte, vous violez la règle Principe de la sécheresse donc, à moins d'avoir une très bonne raison, vous ne devriez pas le faire.

0 votes

Aaarrgghh - J'étais désespérément en train de chercher ça sur Google mais j'ai oublié comment ça s'appelait !

6voto

Une autre approche consiste à utiliser une constante initialisée au-dessus 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 vous évitez la surcharge 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