在Java中迭代枚举的for循环

我有一个enum在Java的基本和中间方向:

public enum Direction {NORTH,NORTHEAST,EAST,SOUTHEAST,SOUTH,SOUTHWEST,WEST,NORTHWEST}

如何编写一个for循环来迭代这些enum值中的每一个?

506192 次浏览

枚举类型的所有常量都可以通过调用该类型的隐式public static T[] values()方法获得:

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

.values()

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

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

这个values()方法是由编译器隐式声明。所以它没有在Enum文档中列出。

你可以这样做如下:

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

如果你不关心顺序,这应该工作:

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

8Java之前

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

Java8

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

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

为什么forEachOrdered而不是forEach与流?

forEach的行为是显式不确定的,因为forEachOrdered对这个流的每个元素执行一个操作,如果流有定义的遇到顺序,则按照流的遇到顺序执行。所以forEach不保证顺序会被保留。

同样,在处理流(尤其是并行流)时,请记住流的性质。根据doc

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

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

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

一般来说,不鼓励流操作的行为参数中的副作用,因为它们通常会导致无意中违反无状态要求,以及其他线程安全隐患。

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

java8

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

从java5+

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

java 8中的更多方法:

使用EnumSetforEach

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

使用Arrays.asListforEach

Arrays.asList(Direction.values()).forEach(...);

我们可以使用这样的过滤器(JAVA 8)。

Stream.of(Direction.values()).filter(name -> !name.toString().startsWith("S")).forEach(System.out::println);

场景:假设我们有固定数量的卡片类型。每种卡类型都有费用和与之相关的加入奖金。

package enumPkg;
public enum CardTypes {//Each enum is objectDEBIT(10,20),CREDIT(0,10),CRYPTO(5,30);
//Object propertiesint fees;int bonus;
//Initilize object using constructorCardTypes(int fee, int bonus){this.fees = fee;this.bonus = bonus;}
//access object propertypublic int getFees(){return this.fees;}
public int getBonus(){return this.bonus;}
}

现在访问其他类中的枚举。在Java中遵循以下过程:

package enumPkg;
public class EnumClass {public static void main(String[] args) {CardTypes cardType = CardTypes.CREDIT; //Each enum element is public static final, when accessed returns a objectSystem.out.println(cardType);
System.out.println("Debit card fees : "+CardTypes.DEBIT.getFees());System.out.println("Debit card bonus : "+CardTypes.DEBIT.getBonus());
CardTypes[] cardTypes = CardTypes.values();//return array of CardTypes i.e all enum elements we have defined
for (CardTypes type : CardTypes.values()) {System.out.println(type); //particular enum objectSystem.out.println(type.ordinal()); //return enum positionSystem.out.println("Bonus : "+type.getBonus()); //return enum object property: BonusSystem.out.println("Fees  : "+type.getFees());//return enum object property: Fees}
}}

输出:

CREDITDebit card fees : 10Debit card bonus : 20DEBIT0Bonus : 20Fees  : 10CREDIT1Bonus : 10Fees  : 0CRYPTO2Bonus : 30Fees  : 5