2009-11-16 3 views
50

Ich habe Aufzählung wie folgt aus:Enum values ​​() Länge vs privaten Bereich

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

Manchmal muss ich überprüfen, wie viele Felder, die ich in Aufzählung haben. Was ist die beste Lösung? Sollte ich eine Methode "values ​​(). Length" verwenden? Oder vielleicht muss ich ein konstantes Feld in der Aufzählung wie folgt erstellen:

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

Was ist die schnellste und eleganteste Lösung?

Antwort

87

Die Verwendung von values().length erstellt bei jedem Aufruf eine neue Kopie des Arrays. Manchmal erstelle ich meine eigene List (oder setze oder mappe, was ich brauche), um dieses sinnlose Kopieren zu vermeiden. Ich würde nicht hart Code es aber ... wenn Sie nur die Größe benötigen, würde ich nur verwenden:

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

am Ende. Bis zur Auswertung werden alle Werte initialisiert. Dies vermeidet die in anderen Antworten aufgeworfenen DRY- und Inkonsistenzen.

Natürlich ist dies ein bisschen eine Mikro-Optimierung in sich selbst ... aber eine, die am Ende mit einfacher Code endet, IMO. values().length von woanders anzurufen drückt nicht aus, woran Sie interessiert sind, das ist nur die Größe der Enum - die Tatsache, dass Sie durch eine Reihe von Werten erhalten Sie zufällig und ablenkend, IMO.

Eine Alternative zur Verwendung values() ist die Verwendung EnumSet.allOf().size(), die für kleine Enums wird ziemlich billig sein - aber wieder, es ist nicht so lesbar wie nur ein size Feld.

+1

Wenn Sie die Java-Namenskonventionen einhalten möchten, sollten Sie diese Konstante 'SIZE' nicht als' Größe' bezeichnen? – Jubobs

+0

@Jubobs: Ich würde sicherlich für eine öffentliche Konstante, aber für eine private ist mir egal, egal wie. Beachten Sie, dass es keine * Kompilierzeit * -Konstante ist. –

+0

Vielen Dank für Ihre Begründung. – Jubobs

9

Ich würde empfehlen, values().length zu verwenden. Dies ist viel eleganter und der Leistungsaufwand gegenüber der Verwendung einer Konstanten ist vernachlässigbar. Außerdem eliminieren Sie das Risiko, dass die Konstante mit der tatsächlichen Länge der Aufzählung Schritt hält.

7

Durch die Speicherung der Zählung verletzen Sie die DRY principle, also wenn Sie nicht einen sehr guten Grund haben, sollten Sie nicht.

+0

Aaarrgghh - Ich habe verzweifelt gegoogelt, aber vergessen, wie es heißt! – Adamski

3

Ein anderer Ansatz besteht darin, eine Konstante zu verwenden, die über die Methode values ​​() initialisiert wird.

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

Auf diese Weise haben Sie eine automatisch aktualisierte Konstante und immer noch vermeiden, dass "values ​​()" Overhead.