Цикл for для перебора перечисления в Java

745

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

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

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

Теги:
for-loop
enums

11 ответов

1294
Лучший ответ

.values()

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

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

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

  • 42
    Почему этот метод values () не указан здесь в java.lang.enum
  • 77
    @jacktrades: это неявный метод, который существует только в компиляторе. Поэтому базовый класс не может объявлять метод с тем же именем и, следовательно, он не включается в автоматически генерируемые Javadocs. docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2
Показать ещё 1 комментарий
113

Enum # значения():

 for (Direction d : Direction.values()) {
     System.out.println(d);
 }
  • 0
    @ RAnders00 Правда. Но все же ответ действителен, и формат действительно не имеет значения (по крайней мере для меня)
  • 0
    Что делает # ?
Показать ещё 3 комментария
58

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

for (Direction direction : EnumSet.allOf(Direction.class)) {
  // do stuff
}
  • 1
    При условии, что вы импортируете java.util.EnumSet
  • 8
    Супер полезно для циклов foreach Java8. EnumSet.allOf (Enum.class) .forEach (бла -> метод (бла))
Показать ещё 4 комментария
33

Streams

До Java 8

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

Java 8

Мы также можем использовать лямбда и потоки (Tutorial):

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

Почему forEachOrdered а не forEach с потоками?

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

Также при работе с потоками (особенно параллельными) следует учитывать природу потоков. Согласно документу:

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

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

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

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

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

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

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

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

Set<Direction> directions = EnumSet.allOf(Direction.class);
for(Direction direction : directions) {
    // do stuff
}
  • 2
    При условии, что вы импортируете java.util.EnumSet и java.util.Set
  • 4
    Из документации для EnumSet : Итератор, возвращенный методом итератора, EnumSet элементы в их естественном порядке (порядок, в котором объявлены константы перечисления) . Это гарантирует, что порядок итерации соответствует порядку, возвращенному Enum.values() .
4

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

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

Java8

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

из Java5 +

for ( Direction d: Direction.values()){
 System.out.println(d);
}
  • 1
    ой, извини. Я только что понял, что akhil_mittal уже выложил подобный ответ.
  • 0
    Когда и почему я должен использовать Stream.of (o) .forEach? Цикл for кажется гораздо более читабельным.
Показать ещё 1 комментарий
2

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

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

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

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

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

Вот как перебирать 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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню