我需要数组中的EnumSet
(通过varargs方法参数给出)。首先,我很惊讶EnumSet
中没有varargs构造函数方法(有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);
当然,如果这可以转移到某种实用方法,但我仍然在问自己是否有使用现有方法的更简单的方法?
两行,但稍微不那么复杂:
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
只是一个替代方案。相同数量的代码,除了不需要转换为列表,使用 EnumSet.of():
EnumSet<Options> temp = options.length > 0 ?
EnumSet.of(options[0], options) :
EnumSet.noneOf(Options.class);
不用担心第一个元素重复(无论如何它不会在一个集合中复制),也没有性能提升或惩罚。
Guava有针对以下情况的工厂方法:它仍然需要调用 Arrays.asList,但至少它是可读的。
import com.google.common.collect.Sets;
EnumSet<Options> temp = Sets.newEnumSet(Arrays.asList(options), Options.class);
你也可以使用 Java8 流和你自己的 CollectionFactory 来做到这一点:
EnumSet<Options> temp = Arrays.stream(options)
.collect(Collectors.toCollection(() -> EnumSet.noneOf(Options.class)));
最简单的解决方案是显而易见的:如果您可以访问正在使用的方法的签名,那么只需将EnumSet.of(T first, T ... more)
的签名模仿为
void myMethod(Options first, Options ... rest) {
EnumSet<Options> temp = EnumSet.of(first, rest);
}
由于省略号已经是方法参数列表的最后一个元素(因为它必须是),这不会更改任何调用代码,并且不需要跳过循环。