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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22886287/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 18:40:26  来源:igfitidea点击:

EnumSet from array, shortest variant?

javaarraysenumsvariadic-functionsenumset

提问by qqilihq

I need an EnumSetfrom an array (which is given through a varargs method parameter). First, I was surprised that there is no varargs constructor method in EnumSet(there is EnumSet#of(E first, E... rest)). As a workaround, I used the following variant:

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

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

However, this triggers a java.lang.IllegalArgumentException: Collection is empty. So, now I ended up with the following, which looks somewhat ridiculous:

但是,这会触发java.lang.IllegalArgumentException: Collection is empty. 所以,现在我结束了以下内容,这看起来有些荒谬:

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

If course this could be moved to some utility method, but still, I'm asking myself if there is a simpler way using existing methods?

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

采纳答案by azurefrog

This is two lines, but slightly less complex:

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

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

I don't consider this worse than any other kind of variable declaration for a class which doesn't have the constructor you want:

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

    SomeClass variable = new SomeClass(); // make an empty object
    variable.addStuff(stuff); // add stuff to it

回答by kiruwka

Just an alternative. Same amount of code, except no need converting to list, using EnumSet.of():

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

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

No worries that first element is repeated(it won't be duplicated in a set anyway), no performance gain or penalties as well.

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

回答by Scheintod

The simplest solution is the obvious one: If you have access to the method's signature you are using then just mimic the signature of EnumSet.of(T first, T ... more)as

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

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

As the ellipsis is already the last element of your method's parameters list (because it has to be) this won't change any calling code and you don't need to jump through loops.

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

回答by Johan Tidén

Guava has factory methods for these kinds of situations: It still needs the call to Arrays.asList but at least it's readable.

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

import com.google.common.collect.Sets;

EnumSet<Options> temp = Sets.newEnumSet(Arrays.asList(options), Options.class);

回答by dkarp

You can also do this with Java8 streams and your own CollectionFactory:

你也可以使用 Java8 流和你自己的 CollectionFactory 来做到这一点:

EnumSet<Options> temp = Arrays.stream(options)
        .collect(Collectors.toCollection(() -> EnumSet.noneOf(Options.class)));