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

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

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

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

9.07.2009 16:24:03
akhil_mittal 21.09.2018 05:30:23
10 ОТВЕТОВ
РЕШЕНИЕ

.values()

Вы можете вызвать values()метод в вашем enum.

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

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

1394
21.07.2015 20:24:16
Почему этот метод values ​​() не указан здесь в java.lang.enum
jacktrades 17.01.2013 01:12:30
@jacktrades: это неявный метод, который существует только в компиляторе. Поэтому базовый класс не может объявлять метод с тем же именем, и поэтому он не включается в автоматически сгенерированные Javadocs. docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2
Torben 5.03.2013 09:32:53
Как ни странно, это упоминается в документе valueOf ()
greg7gkb 3.09.2017 22:11:58

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

 for (Direction d : Direction.values()) {
     System.out.println(d);
 }
129
1.10.2019 20:07:54
@ RAnders00 Правда. Но все же ответ действителен, и формат действительно не имеет значения (по крайней мере для меня)
dARKpRINCE 8.02.2016 14:25:11
Что делает #?
YoTengoUnLCD 11.06.2016 19:55:48
@YoTengoUnLCD По сути, он говорит, что values ​​() является частью объекта Enum. напр. Enum#values()=Enum.values()
Spotlight 11.06.2016 21:21:00
Хм, прости, я не слежу, это так же, как использовать .(всегда?)?
YoTengoUnLCD 11.06.2016 22:04:19
@YoTengoUnLCD Хэштегом является синтаксис JavaDoc, а не код Java.
Jeff G 31.10.2016 20:16:56

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

for (Direction direction : EnumSet.allOf(Direction.class)) {
  // do stuff
}
62
9.07.2009 16:27:19
При условии, что вы импортируете java.util.EnumSet
Nate 9.07.2009 17:13:37
Супер полезно для циклов foreach Java8. EnumSet.allOf (Enum.class) .forEach (бла -> метод (бла))
Hiro2k 2.06.2015 18:18:17
@ Hiro2k Вы также можете сделать Arrays.stream(Enum.values()).forEach(...)- поток будет последовательным
RAnders00 8.02.2016 12:42:11
@ Schatten хорошо, это setвместо array. Это не «лучше», хотя, на мой взгляд, лучше описывает значения перечисления, потому что из определения множества значения в множестве не могут повторяться (как в перечислении), тогда как значения в массиве могут быть.
Jezor 8.09.2016 13:56:42
@Jezor Это лучший выбор, когда вам действительно нужен очень быстрый набор перечислений, таких как битовые флаги, хотя он кажется слишком сложным для простой итерации.
schatten 8.09.2016 19:02:25

Если вы не заботитесь о заказе, это должно сработать:

Set<Direction> directions = EnumSet.allOf(Direction.class);
for(Direction direction : directions) {
    // do stuff
}
19
9.07.2009 16:27:33
При условии, что вы импортируете java.util.EnumSet и java.util.Set
Nate 9.07.2009 17:15:18
Из документации дляEnumSet : Итератор, возвращенный методом итератора, перебирает элементы в их естественном порядке (порядок, в котором объявлены константы перечисления) . Это гарантирует, что порядок итерации соответствует порядку, возвращенному функцией Enum.values().
Jeff G 31.10.2016 20:23:25
for(Direction dir : Direction.values())
{

}
21
9.07.2009 16:58:07
    for (Direction  d : Direction.values()) {
       //your code here   
    }
18
9.07.2009 16:29:07

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является явно недетерминированным, когда as forEachOrderedвыполняет действие для каждого элемента этого потока, в порядке обнаружения потока, если поток имеет определенный порядок встречи. Так forEachчто не гарантирует, что заказ будет сохранен.

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

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

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

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

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

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

43
5.12.2018 03:18:00
Как и во всех потоковых операциях, следует учитывать отсутствие потоков и ограничения побочных эффектов. Docs.oracle.com/javase/8/docs/api/java/util/stream/… . Эти 2 варианта итерации enum значительно отличаются в этом отношении.
buzz3791 4.12.2018 23:10:44

Java8

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

с Java5 +

for ( Direction d: Direction.values()){
 System.out.println(d);
}
5
25.02.2016 06:21:25
ой, извини. Я только что понял, что akhil_mittal уже выложил подобный ответ.
Raghu K Nair 25.02.2016 06:22:18
Когда и почему я должен использовать Stream.of (o) .forEach? Цикл for кажется гораздо более читабельным.
Jeremy 3.05.2016 14:46:02
Нет, если вы знакомы с функциональным программированием.
Alexis Dufrenoy 14.12.2016 15:37:48

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

for ( Direction direction : Direction.values()){
  System.out.println(direction.toString());
}
5
23.06.2016 06:50:40

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

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

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

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

Arrays.asList(Direction.values()).forEach(...);
4
23.05.2018 18:46:11