用于遍历Java枚举的“ for”循环


Answers:


1400

.values()

您可以values()在枚举上调用该方法。

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

values()方法由编译器隐式声明。因此它未在Enum文档中列出。


43
为什么这种方法值()未上市这里下java.lang.Enum中
jacktrades

80
@jacktrades:这是仅在编译器中存在的隐式方法。因此,基类不能声明具有相同名称的方法,因此它不会包含在自动生成的Javadocs中。 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 '16

@YoTengoUnLCD基本上是说values()是Enum对象的一部分。例如Enum#values()=Enum.values()
聚焦

嗯,对不起,我不了解,这与使用.(总是吗?)相同吗?
YoTengoUnLCD '16

3
@YoTengoUnLCD标签是JavaDoc语法,而不是Java代码。
杰夫G

62

您可以按照以下步骤进行操作:

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

1
如果您导入了java.util.EnumSet
Nate,2009年

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当您实际上需要一组非常快速的枚举(例如位标志)时,这是一个更好的选择,尽管对于简单的迭代而言似乎太复杂了。
schatten

44

Java 8之前的版本

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

Java 8

我们还可以使用lambda和流(Tutorial):

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

为什么forEachOrderedforEach使用流?

的行为forEach是明确不确定的,其中,forEachOrdered如果流具有已定义的遇到顺序,则在执行此流的每个元素的操作时,将按流的遇到顺序对其进行操作。因此forEach,不能保证将保留订单。

同样,在使用流(尤其是并行流)时,请记住流的性质。根据文档

如果流操作的行为参数是有状态的,则流管道结果可能不确定或不正确。有状态lambda是一种有状态的lambda,其结果取决于在流管道执行期间可能更改的任何状态。

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

在这里,如果并行执行映射操作,则由于线程调度差异,同一输入的结果可能因运行而异,而使用无状态lambda表达式时,结果将始终相同。

通常,不要鼓励行为参数对流操作的副作用,因为它们经常会导致无意识地违反无状态要求以及其他线程安全危害。

流可能具有也可能没有定义的遇到顺序。流是否具有遇到顺序取决于源和中间操作。


与所有流操作一样,请注意线程无状态和副作用限制docs.oracle.com/javase/8/docs/api/java/util/stream/…。在这方面,这两个枚举迭代选项明显不同。
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.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

什么时候以及为什么要使用Stream.of(o).forEach?for循环似乎更具可读性。
杰里米(Jeremy)

如果您熟悉函数式编程,则不会。
亚历克西斯·杜弗洛尼

5

尝试对每个使用

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

4

Java 8中的更多方法:

使用EnumSetforEach

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

使用Arrays.asListforEach

Arrays.asList(Direction.values()).forEach(...);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.