42

我需要一个EnumSet来自数组的(通过 varargs 方法参数给出)。EnumSet首先,令我惊讶的是(有)中没有可变参数构造函数方法EnumSet#of(E first, E... rest)。作为一种解决方法,我使用了以下变体:

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

但是,这会触发java.lang.IllegalArgumentException: Collection is empty. 所以,现在我得到了以下结果,这看起来有点荒谬:

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

如果当然可以将其移至某些实用方法,但是,我仍然在问自己是否有使用现有方法的更简单方法?

4

5 回答 5

25

只是一种选择。相同数量的代码,除了不需要转换为列表,使用EnumSet.of()

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

不用担心重复第一个元素(无论如何它不会在集合中重复),也没有性能增益或惩罚。

于 2014-04-05T20:38:51.750 回答
23

这是两行,但稍微不那么复杂:

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
于 2014-04-05T20:44:23.737 回答
12

Guava 有针对这些情况的工厂方法:它仍然需要调用 Arrays.asList 但至少它是可读的。

import com.google.common.collect.Sets;

EnumSet<Options> temp = Sets.newEnumSet(Arrays.asList(options), Options.class);
于 2014-11-04T09:00:40.013 回答
8

您也可以使用 Java8 流和您自己的 CollectionFactory 来执行此操作:

EnumSet<Options> temp = Arrays.stream(options)
        .collect(Collectors.toCollection(() -> EnumSet.noneOf(Options.class)));
于 2015-04-07T19:14:41.567 回答
5

最简单的解决方案是显而易见的:如果您可以访问您正在使用的方法的签名,那么只需模仿EnumSet.of(T first, T ... more)as的签名

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

由于省略号已经是方法参数列表的最后一个元素(因为它必须如此),这不会更改任何调用代码,并且您不需要跳过循环。

于 2014-08-09T09:07:36.533 回答