Цикл 'for' для итерации по перечислению в Java

У меня есть enum в Java для кардинального и промежуточного направлений:

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

Как я могу написать цикл for, который выполняет итерацию через каждое из этих значений enum?

Ответ 1

.values()

Вы можете вызвать метод values() для вашего перечисления.

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

Этот values() метод неявно объявляется компилятором. Поэтому он не указан в Enum doc.

Ответ 2

Все константы типа enum можно получить, вызвав неявный метод public static T[] values() этого типа:

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

Ответ 3

Вы можете сделать это следующим образом:

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

Ответ 4

Streams

До 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; })...

Здесь, если операция отображения выполняется параллельно, результаты для одного и того же ввода могут варьироваться от прогона к прогоне из-за различий в планировании потоков, тогда как при использовании лямбда-выражения без состояния результаты всегда будут одинаковыми.

Побочные эффекты в поведенческих параметрах для потоковых операций, как правило, не приветствуются, поскольку они часто могут привести к невольным нарушениям требования о безгражданстве, а также другим угрозам безопасности потоков.

Потоки могут иметь или не иметь определенный порядок встречи. Наличие у потока порядка встречи зависит от источника и промежуточных операций.

Ответ 5

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

}

Ответ 6

Если вам не нужен порядок, который должен работать:

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

Ответ 7

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

Ответ 8

Java8

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

из Java5 +

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

Ответ 9

Попробуйте использовать для каждого

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

Ответ 10

Дополнительные методы в java 8:

Использование EnumSet с forEach

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

Использование Arrays.asList с forEach

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

Ответ 11

Вот как перебирать Enum:

private static void iterateEnumValues() {
        System.out.println("Iterating over Direction enum");
        for(Direction direction : Direction.values())
        {
            System.out.println("Enum = " + direction);
        }
}

Чтобы узнать больше об общих операциях Enum, проверьте следующее: Как использовать Enums в java