EnumSet来自数组,最短的变体?

qqi*_*ihq 25 java arrays enums variadic-functions enumset

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

EnumSet<Options> temp = EnumSet.copyOf(Arrays.asList(options));
Run Code Online (Sandbox Code Playgroud)

但是,这会触发一个java.lang.IllegalArgumentException: Collection is empty.所以,现在我最终得到了以下内容,看起来有些荒谬:

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

如果当然这可以转移到一些实用方法,但仍然,我问自己是否有一种更简单的方法使用现有的方法?

kir*_*wka 17

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

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

不用担心第一个元素会重复出现(无论如何都不会在一个集合中重复),也不会有性能上的提升或惩罚.


azu*_*rog 16

这是两行,但稍微复杂一点:

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

对于没有你想要的构造函数的类,我不认为这比任何其他类型的变量声明更糟糕:

    SomeClass variable = new SomeClass(); // make an empty object
    variable.addStuff(stuff); // add stuff to it
Run Code Online (Sandbox Code Playgroud)

  • `Collections.addAll(temp, options);` 比 `temp.addAll(Arrays.asList(options));` 更干净 (3认同)

Joh*_*dén 6

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

import com.google.common.collect.Sets;

EnumSet<Options> temp = Sets.newEnumSet(Arrays.asList(options), Options.class);
Run Code Online (Sandbox Code Playgroud)

  • 公平起见。问题中没有任何内容表明他们有 java 1.8。此外,图书馆答案可能对已经使用该库的读者有用。我认为读者已经足够成熟,可以自己决定是否包含新库。 (3认同)
  • @gouessej虽然您的评论中的要点有效,但本答案仍然有用且信息丰富.特别值得一提的是,该问题特别提到缺乏一个没有varargs构造函数的惊喜 - 这个带有Guava的答案给出了相同的效果,一行具有相似的语法和可读性.我在这个页面上赞成了所有的答案,因为它们都很聪明或信息丰富. (2认同)

dka*_*arp 6

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

EnumSet<Options> temp = Arrays.stream(options)
        .collect(Collectors.toCollection(() -> EnumSet.noneOf(Options.class)));
Run Code Online (Sandbox Code Playgroud)


Sch*_*tod 5

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

void myMethod(Options first, Options ... rest) {
    EnumSet<Options> temp = EnumSet.of(first, rest);
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这不解决数组为空的情况. (11认同)