utils sets retainall remove metodos linkedset java arrays enums variadic-functions enumset

java - sets - EnumSet de matriz, variante más corta?



set retainall java (5)

Necesito un EnumSet de una matriz (que se da a través de un parámetro del método varargs). Primero, me sorprendió que no haya ningún método de construcción varargs en EnumSet (hay EnumSet#of(E first, E... rest) ). Como solución, utilicé la siguiente variante:

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

Sin embargo, esto activa una java.lang.IllegalArgumentException: Collection is empty . Entonces, ahora terminé con lo siguiente, que parece algo ridículo:

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

Por supuesto, esto podría ser movido a algún método de utilidad, pero aún así, me pregunto si hay una manera más simple de usar los métodos existentes.


La guayaba tiene métodos de fábrica para este tipo de situaciones: aún necesita la llamada a Arrays.asList, pero al menos es legible.

import com.google.common.collect.Sets; EnumSet<Options> temp = Sets.newEnumSet(Arrays.asList(options), Options.class);


La solución más simple es la más obvia: si tiene acceso a la firma del método que está utilizando, simplemente imite la firma de EnumSet.of(T first, T ... more) como

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

Como los puntos suspensivos ya son el último elemento de la lista de parámetros de su método (porque tiene que serlo), esto no cambiará ningún código de llamada y no es necesario saltar a través de los bucles.


Se trata de dos líneas, pero un poco menos complejas:

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

No considero que esto sea peor que cualquier otro tipo de declaración de variable para una clase que no tiene el constructor que desea:

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


Solo una alternativa. La misma cantidad de código, excepto que no hay necesidad de convertir a la lista, usando EnumSet.of() :

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

No se preocupe de que el primer elemento se repita (no se duplicará en un conjunto de todos modos), tampoco hay ganancias de rendimiento o penalizaciones.


También puede hacer esto con secuencias Java8 y su propia Colección de Fábrica:

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