web-dev-qa-db-ja.com

配列からのEnumSet、最短のバリアント?

配列からの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);

もちろん、これをいくつかのユーティリティメソッドに移動できたとしても、それでも、既存のメソッドを使用するより簡単な方法があるかどうかを自問しています。

28
qqilihq

これは2行ですが、少し複雑ではありません。

    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
15
azurefrog

ただの選択肢。 EnumSet.of() を使用して、リストに変換する必要がないことを除いて、同じ量のコード:

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

最初の要素が繰り返される心配はありません(いずれにしてもセットで複製されることはありません)。パフォーマンスの向上やペナルティもありません。

18
kiruwka

Java8ストリームと独自のCollectionFactoryを使用してこれを行うこともできます。

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

Guavaには、このような状況に対応するファクトリメソッドがあります。Arrays.asListの呼び出しが必要ですが、少なくとも読み取り可能です。

import com.google.common.collect.Sets;

EnumSet<Options> temp = Sets.newEnumSet(Arrays.asList(options), Options.class);
5
Johan Tidén

最も簡単な解決策は明白なものです。使用しているメソッドのシグネチャにアクセスできる場合は、EnumSet.of(T first, T ... more)のシグネチャを模倣するだけです。

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

省略記号はすでにメソッドのパラメーターリストの最後の要素であるため(そうする必要があるため)、呼び出しコードは変更されず、ループをジャンプする必要もありません。

5
Scheintod