Javaの列挙型を反復する「for」ループ


回答:


1400

.values()

values()列挙型でメソッドを呼び出すことができます。

for (Direction dir : Direction.values()) {
  // do what you want
}

このvalues()メソッドはコンパイラによって暗黙的に宣言されます。そのため、Enumドキュメントには記載されていません。


43
このメソッドvalues()がjava.lang.enumの下にリストされいない理由
jacktrades

80
@jacktrades:コンパイラにのみ存在する暗黙のメソッドです。したがって、基本クラスは同じ名前のメソッドを宣言できないため、自動生成されたJavadocに含まれません。 docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2
Torben

4
奇妙なことに、それに記載されているのvalueOf()ドキュメント
greg7gkb

129

列挙型のすべての定数は、public static T[] values()その型の暗黙のメソッドを呼び出すことによって取得できます。

 for (Direction d : Direction.values()) {
     System.out.println(d);
 }

@ RAnders00正しい。しかし、答えは有効であり、形式は本当に重要ではありません(少なくとも私にとっては)
dARKpRINCE

何をし#ますか?
YoTengoUnLCD 2016年

@YoTengoUnLCD基本的に、values()はEnumオブジェクトの一部であると言っています。例Enum#values()=Enum.values()
Spotlight

うーん、ごめんなさい、フォローしません、それは.(いつも?)を使うのと同じですか?
YoTengoUnLCD 2016年

3
@YoTengoUnLCDハッシュタグはJavaDoc構文であり、Javaコードではありません。
ジェフG

62

これは次のようにして行うことができます。

for (Direction direction : EnumSet.allOf(Direction.class)) {
  // do stuff
}

1
あなたはjava.util.EnumSetインポート提供
ネイト

8
Java8 foreachループに非常に役立ちます。EnumSet.allOf(Enum.class).forEach(blah-> method(blah))
Hiro2k

1
@ Hiro2k次のようにすることもできますArrays.stream(Enum.values()).forEach(...)-ストリームは順次になります
RAnders00

1
@schattenよく、それはのset代わりですarray。セットの定義から、セットの値は(列挙型のように)繰り返すことはできませんが、配列の値は繰り返すことができるため、「より良い」とは言えません。
Jezor

2
@Jezorビットフラグのような非常に高速な列挙型のセットが実際に必要な場合は、より良い選択ですが、単純な反復には複雑すぎるようです。
2016

44

ストリーム

Java 8より前

for (Direction dir : Direction.values()) {
            System.out.println(dir);
}

Java 8

ラムダとストリームを使用することもできます(チュートリアル):

Stream.of(Direction.values()).forEachOrdered(System.out::println);

なぜストリームforEachOrderedではないのforEachですか?

の動作forEachは明示的に非決定的forEachOrderedです。ストリームが定義済みの遭遇順序を持っている場合、はこのストリームの各要素のアクションをストリームの遭遇順序で実行します。したがってforEach、注文が保持されることは保証されません。

また、ストリーム(特に並列ストリーム)を使用する場合は、ストリームの性質に注意してください。ドキュメントに従って:

ストリームオペレーションの動作パラメータがステートフルである場合、ストリームパイプラインの結果は非決定的または不正確になる可能性があります。ステートフルラムダは、ストリームパイプラインの実行中に変化する可能性のあるすべての状態に依存するラムダです。

Set<Integer> seen = Collections.synchronizedSet(new HashSet<>());
stream.parallel().map(e -> { if (seen.add(e)) return 0; else return e; })...

ここで、マッピング操作が並列に実行されると、スレッドスケジューリングの違いにより、同じ入力の結果が実行ごとに異なる可能性がありますが、ステートレスラムダ式では、結果は常に同じになります。

ストリーム操作に対する動作パラメータの副作用は、一般に推奨されません。これらは、無意識の要件の意図しない違反や、その他のスレッドセーフティの危険につながることが多いためです。

ストリームには、定義されたエンカウンター順序がある場合とない場合があります。ストリームに遭遇順序があるかどうかは、ソースと中間操作に依存します。


すべてのストリーム操作と同様に、スレッドのステートレスと副作用の制限docs.oracle.com/javase/8/docs/api/java/util/stream/…に注意してください。これらの2つの列挙型反復オプションは、この点で大きく異なります。
buzz3791


19

注文を気にしない場合、これはうまくいくはずです:

Set<Direction> directions = EnumSet.allOf(Direction.class);
for(Direction direction : directions) {
    // do stuff
}

2
java.util.EnumSetとjava.util.Setをインポートする場合
Nate

4
以下からのドキュメントのためのEnumSetiteratorメソッドによって返される反復子その中の要素を横断自然順序(enum定数の宣言された順)。これにより、反復の順序がによって返される順序と一致することが保証されEnum.values()ます。
ジェフG

18
    for (Direction  d : Direction.values()) {
       //your code here   
    }

5

Java8

Stream.of(Direction.values()).forEach(System.out::println);

Java5以降

for ( Direction d: Direction.values()){
 System.out.println(d);
}

1
あ、ごめんなさい。akhil_mittalがすでに同様の回答を投稿していることに気づきました。
Raghu K Nair 2016

いつ、なぜStream.of(o).forEachを使用する必要がありますか?forループの方が読みやすいようです。
ジェレミー

関数型プログラミングに精通している場合は必要ありません。
Alexis Dufrenoy 2016

5

それぞれに使用してみてください

for ( Direction direction : Direction.values()){
  System.out.println(direction.toString());
}

4

Java 8のその他のメソッド:

使用EnumSetしてforEach

EnumSet.allOf(Direction.class).forEach(...);

使用する Arrays.asListしてforEach

Arrays.asList(Direction.values()).forEach(...);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.