2017-02-24 1 views
4

すべての列挙値を繰り返し処理する必要があります。それらがint( "input")を構築するために使用されたかどうかを確認し、そうであればそれらをセット(usefulEnums)に追加します。ストリームAPIを使用するか、このタスクを実行するためにすべての列挙型を反復処理できます。 Arrays.stream()を、values()アレイに対して反復処理する伝統的な方法に比べて利点はありますか?この短い動作のためArrays.stream()を配列の反復処理よりもパフォーマンス上のメリットはありますか?

enum TestEnum { VALUE1, VALUE2, VALUE3 }; 

    Set<TestEnum> usefulEnums = new HashSet<>(); 

    Arrays.stream(TestEnum.values()) 
      .filter(t -> (input & t.getValue()) != 0) 
      .forEach(usefulEnums::add); 

    for (TestEnum t : TestEnum.values()) { 
     if ((input & t.getValue()) != 0) { 
      usefulEnums.add(t); 
     } 
    } 

答えて

2

for loopは、(ナノ秒より速い)より高速になるだろうが、私には、ストリーム操作がmore verboseあり、それはここで行われている正確に何を伝えます。それは斜めに読むことのようなものです。

また、あなたがHashSetに直接収集することができます:

Arrays.stream(TestEnum.values()) 
     .filter(t -> (input & t.getValue()) != 0) 
     .collect(Collectors.toCollection(HashSet::new)); 
いつものようにホルガーから

貴重な入力がこれも立派になり:あなたは、効率の世話をした場合

EnumSet<TestEnum> filtered = EnumSet.allOf(TestEnum.class).stream() 
      .filter(t -> (input & t.getValue()) != 0) 
      .collect(Collectors.toCollection(() -> EnumSet.noneOf(TestEnum.class))); 
+0

パーフェクト!ありがとうございました:) – user1071840

+1

'Set'だけが必要な一般的なケースでは、特に' HashSet'ではなく、 'Collectors.toSet()'が望ましいです。 –

+1

@ Solomonoff's Secret:要素が 'TestEnum'のようなenum定数である場合、代わりに' Collectors.toCollection(() - > EnumSet.noneOf(TestEnum.class)) 'を使うのが好ましいかもしれません。述語にマッチする 'enum'定数は、単純な単純な解決策を持っています。 – Holger

3

、あなたが考慮する必要があります。

Set<TestEnum> usefulEnums = EnumSet.allOf(TestEnum.class); 
usefulEnums.removeIf(t -> (input & t.getValue()) == 0); 

すべてを繰り返し処理する必要がある場合は、enumタイプの定数の場合、EnumSet.allOf(EnumType.class).stream()を使用すると、配列の作成は完全にEnumType.values()になりませんが、大部分のenumタイプでは、これを行うには十分な定数がありません。さらに、JVMのオプティマイザは、仮配列の作成を削除することがあります。

しかし、結果はSet<TestEnum>ことになっているこの特定のタスクのために、EnumSet代わりにHashSetを使用することもSetで作業以降の動作を改善することができます。すべての定数を保持し、上記のソリューションのような意図しない定数を削除するEnumSetを作成すると、0b111longを初期化した後、不一致要素のビットをクリアします。

+1

'は' JumboEnumSet'が使用されるときに64個以上のエントリを持たない限り、0b111でlongを初期化するだけです。 'EnumSet.allOf'についての良い点 – Eugene

+1

@Eugene:よく' 0b111'は明らかに3つの定数の質問の場合を示しています。 'enum'の定数が' 64 'の場合は '0b1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111'となりますが、それ以上あれば' long [] '配列がありますが、' TestEnum [] '目立つようになり、 'EnumSet'の利点をさらに大きくします。 – Holger

+0

@Holger '' 0b111でlongを初期化するだけであることを説明できますか? – user1071840

関連する問題