Une boucle «pour» pour itérer sur une énumération en Java


Réponses:


1400

.values()

Vous pouvez appeler la values()méthode sur votre énumération.

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

Cette values()méthode est implicitement déclarée par le compilateur . Il n'est donc pas répertorié dans le Enumdoc.


43
Pourquoi cette méthode values ​​() n'est pas répertoriée ici sous java.lang.enum
jacktrades

80
@jacktrades: C'est une méthode implicite qui n'existe que dans le compilateur. Par conséquent, la classe de base ne peut pas déclarer une méthode du même nom et n'est donc pas incluse dans les Javadocs générés automatiquement. docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2
Torben

4
Curieusement, il est mentionné dans les documents valueOf ()
greg7gkb

129

Toutes les constantes d'un type enum peuvent être obtenues en appelant la public static T[] values()méthode implicite de ce type:

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

@ RAnders00 True. Mais la réponse est toujours valable et le format n'a vraiment pas d'importance (du moins pour moi)
dARKpRINCE

Que fait le #?
YoTengoUnLCD

@YoTengoUnLCD Fondamentalement, cela signifie que values ​​() fait partie de l'objet Enum. par exemple Enum#values()=Enum.values()
Spotlight

Hmm, je suis désolé, je ne suis pas, est-ce la même chose que d'utiliser .(toujours?)?
YoTengoUnLCD

3
@YoTengoUnLCD Le hashtag est la syntaxe JavaDoc, pas le code Java.
Jeff G

62

Vous pouvez le faire comme suit:

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

1
Pourvu que vous importiez java.util.EnumSet
Nate

8
Super utile pour les boucles foreach Java8. EnumSet.allOf (Enum.class) .forEach (blah -> method (blah))
Hiro2k

1
@ Hiro2k Vous pourriez aussi le faire Arrays.stream(Enum.values()).forEach(...)- le flux sera séquentiel
RAnders00

1
@ schatten bien, c'est un setlieu de array. Ce n'est pas "mieux", bien qu'il décrive mieux les valeurs d'énumération, car d'après la définition de set, les valeurs de set ne peuvent pas être répétées (comme dans enum), alors que les valeurs dans array peuvent l'être.
Jezor

2
@Jezor C'est un meilleur choix lorsque vous avez réellement besoin d'un ensemble d'énumérations très rapides, comme des indicateurs de bits, mais cela semble trop compliqué pour une simple itération.
schatten

44

Ruisseaux

Avant Java 8

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

Java 8

Nous pouvons également utiliser lambda et les streams ( Tutorial ):

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

Pourquoi forEachOrderedet non forEachavec des streams?

Le comportement de forEachest explicitement non déterministe alors que le forEachOrderedeffectue une action pour chaque élément de ce flux, dans l'ordre de rencontre du flux si le flux a un ordre de rencontre défini. forEachNe garantit donc pas que la commande sera conservée.

De plus, lorsque vous travaillez avec des flux (en particulier des flux parallèles), gardez à l'esprit la nature des flux. Selon le doc :

Les résultats du pipeline de flux peuvent être non déterministes ou incorrects si les paramètres de comportement des opérations de flux sont avec état. Un lambda avec état est un dont le résultat dépend de tout état qui pourrait changer pendant l'exécution du pipeline de flux.

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

Ici, si l'opération de mappage est effectuée en parallèle, les résultats pour la même entrée peuvent varier d'une exécution à l'autre, en raison de différences de planification des threads, tandis qu'avec une expression lambda sans état, les résultats seraient toujours les mêmes.

Les effets secondaires des paramètres de comportement pour les opérations de flux sont, en général, découragés, car ils peuvent souvent conduire à des violations involontaires de l'apatridie, ainsi qu'à d'autres dangers liés à la sécurité des threads.

Les flux peuvent avoir ou non un ordre de rencontre défini. Le fait qu'un flux ait ou non un ordre de rencontre dépend de la source et des opérations intermédiaires.


Comme pour toutes les opérations de flux, soyez conscient de l'apatridie des threads et des limites des effets secondaires docs.oracle.com/javase/8/docs/api/java/util/stream/… . Ces deux options d'énumération sont sensiblement différentes à cet égard.
buzz3791


19

Si vous ne vous souciez pas de la commande, cela devrait fonctionner:

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

2
Pourvu que vous importiez java.util.EnumSet et java.util.Set
Nate

4
De la documentation deEnumSet : L'itérateur retourné par la méthode itérateur traverse les éléments dans leur ordre naturel (l'ordre dans lequel les constantes d'énumération sont déclarées) . Cela garantit que l'ordre d'itération correspond à la commande retournée par Enum.values().
Jeff G

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

5

Java8

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

de Java5 +

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

1
Oh pardon. Je viens de réaliser que akhil_mittal a déjà posté la même réponse.
Raghu K Nair le

Quand et pourquoi devrais-je utiliser Stream.of (o) .forEach? La boucle for semble beaucoup plus lisible.
Jeremy

Pas si vous connaissez la programmation fonctionnelle.
Alexis Dufrenoy

5

Essayez d'utiliser un pour chacun

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

4

Plus de méthodes dans java 8:

Utilisation EnumSetavecforEach

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

Utilisation Arrays.asListavecforEach

Arrays.asList(Direction.values()).forEach(...);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.