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

avatar
Nick Meyer
9 июля 2009 в 16:24
483551
12
899

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

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

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

Источник
akhil_mittal
21 сентября 2018 в 05:30
0

Java 8: coderhelper.com/a/30962181/1216775

Ответы (12)

avatar
notnoop
9 июля 2009 в 16:27
1444

.values()

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

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

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

jacktrades
17 января 2013 в 01:12
45

Почему этот метод values ​​() не указан здесь в java.lang.enum

Torben
5 марта 2013 в 09:32
81

@jacktrades: это неявный метод, который существует только в компиляторе. Поэтому базовый класс не может объявить метод с тем же именем и, следовательно, не будет включен в автоматически сгенерированную документацию Javadocs. docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2

greg7gkb
3 сентября 2017 в 22:11
4

Как ни странно, это упоминается в valueOf () docs

avatar
nabayram
26 января 2021 в 18:20
1

метод values ​​() может просто работать:

for (Direction  d : Direction.values()) {
   //whatever you want to do with each of these enum values  
}
phoenixstudio
26 января 2021 в 19:44
0

Ваш ответ такой же, как и здесь: coderhelper.com/a/1104994/11876201, попробуйте, пожалуйста, объясните больше, чтобы ваш ответ был более полезным

avatar
Sarat Kumar
16 августа 2020 в 05:42
1

мы можем использовать такой фильтр (JAVA 8).

Stream.of(Direction.values()).filter(name -> !name.toString().startsWith("S")).forEach(System.out::println);
avatar
NiVeR
23 мая 2018 в 18:46
4

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

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

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

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

Arrays.asList(Direction.values()).forEach(...);
avatar
Irazza
23 июня 2016 в 06:50
5

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

for ( Direction direction : Direction.values()){
  System.out.println(direction.toString());
}
avatar
Raghu K Nair
25 февраля 2016 в 06:21
6

Java8

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

с Java5 +

for ( Direction d: Direction.values()){
 System.out.println(d);
}
Raghu K Nair
25 февраля 2016 в 06:22
1

ой, извини. Я только что понял, что akhil_mittal уже публиковал аналогичный ответ.

Jeremy
3 мая 2016 в 14:46
0

Когда и почему мне следует использовать Stream.of (o) .forEach? Цикл for кажется более читаемым.

Alexis Dufrenoy
14 декабря 2016 в 15:37
0

Нет, если вы знакомы с функциональным программированием.

avatar
akhil_mittal
21 июня 2015 в 07:16
46

Потоки

До 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 не гарантирует, что порядок будет сохранен.

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

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

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

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

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

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

buzz3791
4 декабря 2018 в 23:10
0

Как и в случае со всеми потоковыми операциями, помните об отсутствии состояния потока и ограничениях побочных эффектов docs.oracle.com/javase/8/docs/api/java/util/stream/…. Эти 2 варианта итерации перечисления существенно различаются в этом отношении.

avatar
akf
9 июля 2009 в 16:29
20
    for (Direction  d : Direction.values()) {
       //your code here   
    }
avatar
user101884
9 июля 2009 в 16:28
22
for(Direction dir : Direction.values())
{

}
avatar
Tom Jefferys
9 июля 2009 в 16:27
20

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

Set<Direction> directions = EnumSet.allOf(Direction.class);
for(Direction direction : directions) {
    // do stuff
}
Nate
9 июля 2009 в 17:15
2

Если вы импортируете java.util.EnumSet и java.util.Set

Jeff G
31 октября 2016 в 20:23
4

Из документации для EnumSet: Итератор, возвращаемый методом итератора, проходит элементы в их естественном порядке (порядок, в котором объявлены константы перечисления) <80442587011 >. Это гарантирует, что порядок итерации соответствует порядку, возвращаемому Enum.values().

avatar
toluju
9 июля 2009 в 16:27
62

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

for (Direction direction : EnumSet.allOf(Direction.class)) {
  // do stuff
}
Nate
9 июля 2009 в 17:13
1

Если вы импортируете java.util.EnumSet

Hiro2k
2 июня 2015 в 18:18
8

Очень полезно для циклов foreach в Java8. EnumSet.allOf (Enum.class) .forEach (бла -> метод (бла))

RAnders00
8 февраля 2016 в 12:42
1

@ Hiro2k Можно также сделать Arrays.stream(Enum.values()).forEach(...) - поток будет последовательным

schatten
13 мая 2016 в 23:02
0

Можете объяснить, почему это лучше, чем Enum.values()?

Jezor
8 сентября 2016 в 13:56
1

@schatten ну, это set вместо array. Это не «лучше», хотя, на мой взгляд, он лучше описывает значения перечисления, потому что из определения набора значения в наборе не могут повторяться (как в перечислении), тогда как значения в массиве могут быть.

schatten
8 сентября 2016 в 19:02
2

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

avatar
dfa
9 июля 2009 в 16:26
130

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

 for (Direction d : Direction.values()) {
     System.out.println(d);
 }
dARKpRINCE
8 февраля 2016 в 14:25
0

@ RAnders00 Верно. Но все же ответ верен, и формат действительно не имеет значения (по крайней мере, для меня)

YoTengoUnLCD
11 июня 2016 в 19:55
0

Что делает #?

Spotlight
11 июня 2016 в 21:21
0

@YoTengoUnLCD В основном это говорит о том, что values ​​() является частью объекта Enum. например, Enum#values() = Enum.values()

YoTengoUnLCD
11 июня 2016 в 22:04
0

Хм, извините, я не понимаю, это то же самое, что использовать . (всегда?)?

Jeff G
31 октября 2016 в 20:16
3

@YoTengoUnLCD Хэштег - это синтаксис JavaDoc, а не код Java.