Um loop 'for' para iterar sobre uma enumeração em Java


Respostas:


1400

.values()

Você pode chamar o values()método na sua enumeração.

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

Este values()método é declarado implicitamente pelo compilador . Portanto, não está listado no Enumdocumento


43
Por este método valores () não está listado aqui sob java.lang.Enum
jacktrades

80
@ jacktrades: É um método implícito que existe apenas no compilador. Portanto, a classe base não pode declarar um método com o mesmo nome e, portanto, não é incluído nos Javadocs gerados automaticamente. docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2
Torben

4
Estranhamente, isso é mencionado nos documentos valueOf ()
greg7gkb

129

Todas as constantes de um tipo de enum podem ser obtidas chamando o public static T[] values()método implícito desse tipo:

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

@ RAnders00 True. Mas ainda assim a resposta é válida e o formato realmente não importa (pelo menos para mim)
dARKpRINCE

O que #faz?
YoTengoUnLCD

@YoTengoUnLCD Basicamente, está dizendo que values ​​() faz parte do objeto Enum. por exemplo Enum#values()=Enum.values()
Spotlight

Hmm, desculpe, eu não sigo, é o mesmo que usar .(sempre?)?
YoTengoUnLCD

3
@YoTengoUnLCD A hashtag é uma sintaxe JavaDoc, não um código Java.
Jeff G

62

Você pode fazer isso da seguinte maneira:

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

1
Desde que você importar java.util.EnumSet
Nate

8
Super útil para Java8 foreach loops. EnumSet.allOf (Enum.class) .forEach (blah -> method (blah))
Hiro2k

1
@ Hiro2k Você também pode fazer Arrays.stream(Enum.values()).forEach(...)- o fluxo será seqüencial #
RAnders00 8/16/16

1
@ Chatchat bem, é um em setvez de array. Não é "melhor", embora descreva valores de enum melhor na minha opinião, porque da definição de conjunto, os valores em conjunto não podem ser repetidos (como em enum), enquanto os valores em matriz podem ser.
Jezor

2
@Jezor É uma escolha melhor quando você realmente precisa de um conjunto muito rápido de enumerações, como sinalizadores de bits, embora pareça ser muito complicado para uma iteração simples.
schatten

44

Streams

Antes do Java 8

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

Java 8

Também podemos usar lambda e streams ( Tutorial ):

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

Por que forEachOrderede não forEachcom fluxos?

O comportamento de forEaché explicitamente não determinístico, onde comoforEachOrdered executa uma ação para cada elemento desse fluxo, na ordem de encontro do fluxo, se o fluxo tiver uma ordem de encontro definida. assimforEach , não garante que o pedido seja mantido.

Além disso, ao trabalhar com fluxos (especialmente os paralelos), lembre-se da natureza dos fluxos. De acordo com o documento :

Os resultados do pipeline de fluxo podem não ser determinísticos ou incorretos se os parâmetros comportamentais para as operações de fluxo forem stateful. Um lambda com estado é aquele cujo resultado depende de qualquer estado que possa mudar durante a execução do pipeline de fluxo.

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

Aqui, se a operação de mapeamento for executada em paralelo, os resultados para a mesma entrada podem variar de execução para execução, devido a diferenças de planejamento de encadeamento, enquanto que, com uma expressão lambda sem estado, os resultados sempre serão os mesmos.

Os efeitos colaterais nos parâmetros comportamentais das operações de fluxo são, em geral, desencorajados, pois geralmente podem levar a violações involuntárias do requisito de apatridia, bem como a outros riscos de segurança da thread.

Os fluxos podem ou não ter uma ordem de encontro definida. O fato de um fluxo ter ou não uma ordem de encontro depende da origem e das operações intermediárias.


Como em todas as operações de fluxo, esteja ciente da ausência de estado do thread e dos limites de efeito colateral docs.oracle.com/javase/8/docs/api/java/util/stream/… . Essas duas opções de iteração de enum são significativamente diferentes nesse sentido.
precisa saber é o seguinte


19

Se você não se importa com o pedido, isso deve funcionar:

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

2
Desde que você importar java.util.EnumSet e java.util.Set
Nate

4
Da documentação paraEnumSet : O iterador retornado pelo método do iterador percorre os elementos em sua ordem natural (a ordem na qual as constantes da enumeração são declaradas) . Isso garante que a ordem da iteração corresponda à ordem retornada por Enum.values().
Jeff G

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

5

Java8

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

do Java5 +

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

1
Oh, desculpe. Acabei de perceber que akhil_mittal já postou a resposta semelhante.
Raghu K Nair

Quando e por que devo usar o Stream.of (o) .forEch? O loop for parece muito mais legível.
Jeremy

Não se você estiver familiarizado com a programação funcional.
Alexis Dufrenoy

5

Tente usar um para cada

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

4

Mais métodos em java 8:

Usando EnumSetcomforEach

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

Usando Arrays.asListcomforEach

Arrays.asList(Direction.values()).forEach(...);
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.