繁体   English   中英

在 Java 中迭代枚举的 for 循环

[英]A for-loop to iterate over an enum in Java

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

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

我如何编写一个遍历每个enum值的for循环?

.values()

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

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

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

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

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

您可以按如下方式执行此操作:

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

在 Java 8 之前

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

爪哇 8

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

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

为什么forEachOrdered而不是forEach与流?

forEach的行为是明确的非确定性的,因为forEachOrdered对该流的每个元素执行操作,如果流具有定义的遇到顺序,则按照流的遇到顺序。 所以forEach不保证订单会被保留。

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

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

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

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

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

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

for(Direction dir : Direction.values())
{

}

如果您不关心顺序,这应该有效:

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

Java8

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

来自Java5+

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

尝试为每个使用一个

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

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);

values() 方法可能很简单:

for (Direction  d : Direction.values()) {
   //whatever you want to do with each of these enum values  
}

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

package enumPkg;

public enum CardTypes {
//Each enum is object
DEBIT(10,20),
CREDIT(0,10),
CRYPTO(5,30);

//Object properties
int fees;
int bonus;

//Initilize object using constructor
CardTypes(int fee, int bonus){
    this.fees = fee;
    this.bonus = bonus;
}

//access object property
public 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 object
    System.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 object
        System.out.println(type.ordinal()); //return enum position
        System.out.println("Bonus : "+type.getBonus()); //return enum object property: Bonus
        System.out.println("Fees  : "+type.getFees());//return enum object property: Fees
    }

}
}

输出:

CREDIT
Debit card fees : 10
Debit card bonus : 20
DEBIT
0
Bonus : 20
Fees  : 10
CREDIT
1
Bonus : 10
Fees  : 0
CRYPTO
2
Bonus : 30
Fees  : 5

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM