2014-04-05 14 views
20

Ho bisogno di un EnumSet da un array (che è dato attraverso un parametro metodo varargs). Innanzitutto, sono rimasto sorpreso dal fatto che non ci sia alcun metodo di costruzione dei vararg in EnumSet (c'è EnumSet#of(E first, E... rest)). Per aggirare il problema, ho usato la seguente variante:EnumSet dall'array, variante più corta?

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

Tuttavia, questo innesca un java.lang.IllegalArgumentException: Collection is empty. Così, ora ho finito con la seguente, che sembra un po 'ridicolo:

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

Se Naturalmente questo potrebbe essere spostato a qualche metodo di utilità, ma ancora, sto a chiedermi se c'è un modo più semplice usando metodi esistenti ?

risposta

10

Si tratta di due linee, ma un po 'meno complessa:

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

io non considero questo peggio di qualsiasi altro tipo di dichiarazione di variabile per una classe che non ha il costruttore che si desidera:

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

Solo un'alternativa. Stessa quantità di codice, tranne che non c'è bisogno di conversione all'elenco, utilizzando EnumSet.of():

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

Nessuna preoccupazione che il primo elemento è ripetuto (non verrà duplicato in un set comunque), nessun guadagno prestazioni o sanzioni pure.

3

la soluzione più semplice è la più ovvia: se si ha accesso a firma del metodo che si utilizza poi basta imitare la firma di EnumSet.of(T first, T ... more) come

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

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

Poiché i puntini di sospensione sono già l'ultimo elemento dell'elenco dei parametri del metodo (perché deve essere), ciò non modificherà alcun codice di chiamata e non è necessario saltare i cicli.

+5

Questo non affronta il caso in cui la matrice è vuota. –

3

Guava ha metodi di fabbrica per questi tipi di situazioni: Ha ancora bisogno della chiamata a Arrays.asList ma almeno è leggibile.

import com.google.common.collect.Sets; 

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

Perché aggiungere una libreria di terze parti solo per fare esattamente ciò che si poteva fare già con l'API standard di Java nel 2014? la risposta di dkarp è migliore per me perché non usa una libreria, non crea una lista intermedia e la trovo leggibile anche se la singola riga di codice è un po 'più lunga. Inoltre, Guava ha una grave mancanza di modularità che potrebbe impedire ad alcuni sviluppatori di utilizzarlo. – gouessej

4

È anche possibile fare questo con Java8 corsi d'acqua e il proprio CollectionFactory:

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