EnumSet from array, shortest variant?

老子叫甜甜 提交于 2019-12-23 06:47:18

问题


I need an EnumSet from 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<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:

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?


回答1:


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



回答2:


Just an alternative. Same amount of code, except no need converting to list, using 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.




回答3:


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

import com.google.common.collect.Sets;

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



回答4:


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

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



回答5:


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

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.



来源:https://stackoverflow.com/questions/22886287/enumset-from-array-shortest-variant

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!