2014-04-05 12 views
20

Ich brauche ein EnumSet von einem Array (das durch einen varargs Methodenparameter gegeben ist). Zuerst war ich überrascht, dass es keine Varargs-Konstruktormethode in EnumSet gibt (es gibt EnumSet#of(E first, E... rest)). Als Abhilfe kann, habe ich die folgende Variante:EnumSet aus Array, kürzeste Variante?

EnumSet<Options> temp = EnumSet.copyOf(Arrays.asList(options)); 

Dies ist jedoch ein java.lang.IllegalArgumentException: Collection is empty auslöst. So, jetzt habe ich am Ende der folgenden auf, die etwas lächerlich aussieht:

EnumSet<Options> temp = options.length > 0 ? 
         EnumSet.copyOf(Arrays.asList(options)) : 
         EnumSet.noneOf(Options.class); 

Wenn natürlich diese zu einem gewissen Nutzen Methode bewegt werden konnten, aber immer noch, ich frage mich, ob es eine einfachere Möglichkeit ist es, bestehende Methoden ?

Antwort

10

Dies ist zwei Linien, aber etwas weniger komplex:

EnumSet<Options> temp = EnumSet.noneOf(Options.class); // make an empty enumset 
    temp.addAll(Arrays.asList(options)); // add varargs to it 

ich nicht halten dies schlimmer als jede andere Art von Variablendeklaration für eine Klasse, die nicht den Konstruktor hat Sie wollen:

SomeClass variable = new SomeClass(); // make an empty object 
    variable.addStuff(stuff); // add stuff to it 
15

Nur eine Alternative. Gleiche Menge an Code, mit Ausnahme keine Notwendigkeit zur Liste konvertieren, mit EnumSet.of():

EnumSet<Options> temp = options.length > 0 ? 
         EnumSet.of(options[0], options) : 
         EnumSet.noneOf(Options.class); 

Keine Sorge, dass die erste Element wiederholt wird, ohne Performance-Gewinn oder Strafen als auch (es wird nicht in einem Satz ohnehin dupliziert werden).

3

die einfachste Lösung ist die offensichtlichste: Wenn Sie Zugriff auf die Unterschrift des Verfahrens haben Sie verwenden, dann imitieren nur die Unterschrift von EnumSet.of(T first, T ... more) als

void myMethod(Options first, Options ... rest){ 

    EnumSet<Options> temp = EnumSet.of(first, rest); 
} 

Da die Ellipse bereits das letzte Element der Parameterliste Ihrer Methode ist (weil es sein muss), ändert das keinen Aufrufcode und Sie müssen nicht durch Schleifen springen.

+5

Dies bezieht sich nicht auf den Fall, in dem das Feld leer ist. –

3

Guava hat Factory-Methoden für diese Art von Situationen: Es benötigt immer noch den Aufruf von Arrays.asList, aber zumindest ist es lesbar.

import com.google.common.collect.Sets; 

EnumSet<Options> temp = Sets.newEnumSet(Arrays.asList(options), Options.class); 
+0

Warum eine Drittanbieter-Bibliothek hinzufügen, um genau das zu erreichen, was 2014 mit der Java-Standard-API bereits möglich war? Die Antwort von dkarp ist besser für mich, weil sie keine Bibliothek verwendet, keine Zwischenliste erstellt und ich finde sie lesbar, obwohl die einzelne Codezeile etwas länger ist. Darüber hinaus hat Guava einen gravierenden Mangel an Modularität, was einige Entwickler davon abhalten könnte, sie zu verwenden. – gouessej

4

Sie können dies auch mit Java8 tun Bäche und Ihre eigenen CollectionFactory:

EnumSet<Options> temp = Arrays.stream(options) 
     .collect(Collectors.toCollection(() -> EnumSet.noneOf(Options.class)));