Подтвердить что ты не робот

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

Если этот курс можно перенести на какой-то метод, но все же, я спрашиваю себя, есть ли более простой способ использования существующих методов?

4b9b3361

Ответ 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);
}

Поскольку многоточие уже является последним элементом в списке параметров вашего метода (поскольку оно должно быть), это не изменит любой вызывающий код, и вам не нужно перепрыгивать через циклы.