EnumSet из массива, самый короткий вариант?
Мне нужен EnumSet
из массива (который задается с помощью параметра метода varargs). Во-первых, я был удивлен, что в EnumSet
нет конструктор-метода varargs (есть EnumSet#of(E first, E... rest)
). В качестве обходного пути я использовал следующий вариант:
EnumSet<Options> temp = EnumSet.copyOf(Arrays.asList(options));
Однако это вызывает a java.lang.IllegalArgumentException: Collection is empty
. Итак, теперь у меня получилось следующее, что выглядит несколько смешно:
EnumSet<Options> temp = options.length > 0 ?
EnumSet.copyOf(Arrays.asList(options)) :
EnumSet.noneOf(Options.class);
Если этот курс можно перенести на какой-то метод, но все же, я спрашиваю себя, есть ли более простой способ использования существующих методов?
Ответы
Ответ 1
Это две строки, но немного менее сложные:
EnumSet<Options> temp = EnumSet.noneOf(Options.class); // make an empty enumset
temp.addAll(Arrays.asList(options)); // add varargs to it
Я не считаю это хуже, чем любое другое объявление переменных для класса, в котором нет нужного вам конструктора:
SomeClass variable = new SomeClass(); // make an empty object
variable.addStuff(stuff); // add stuff to it
Ответ 2
Просто альтернатива. То же количество кода, за исключением необходимости конвертировать в список, используя EnumSet.of():
EnumSet<Options> temp = options.length > 0 ?
EnumSet.of(options[0], options) :
EnumSet.noneOf(Options.class);
Не стоит беспокоиться о том, что первый элемент повторяется (в любом случае он не будет дублироваться в наборе), отсутствие производительности или штрафы.
Ответ 3
В Guava есть методы factory для таких ситуаций:
Он по-прежнему нуждается в вызове в Arrays.asList, но, по крайней мере, он доступен для чтения.
import com.google.common.collect.Sets;
EnumSet<Options> temp = Sets.newEnumSet(Arrays.asList(options), Options.class);
Ответ 4
Вы также можете сделать это с помощью потоков Java8 и собственного CollectionFactory:
EnumSet<Options> temp = Arrays.stream(options)
.collect(Collectors.toCollection(() -> EnumSet.noneOf(Options.class)));
Ответ 5
Самое простое решение - очевидное: если у вас есть доступ к используемой вами сигнатуре метода, просто имитируйте сигнатуру EnumSet.of(T first, T ... more)
как
void myMethod(Options first, Options ... rest) {
EnumSet<Options> temp = EnumSet.of(first, rest);
}
Поскольку многоточие уже является последним элементом в списке параметров вашего метода (поскольку оно должно быть), это не изменит любой вызывающий код, и вам не нужно перепрыгивать через циклы.