Pętla „for” do iteracji po wyliczeniu w Javie


Odpowiedzi:


1400

.values()

Możesz wywołać values()metodę na swoim wyliczeniu.

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

Ta values()metoda jest domyślnie zadeklarowana przez kompilator . Więc nie ma go w Enumdokumencie.


43
Dlaczego ta metoda wartości () nie jest wymieniony tutaj pod java.lang.enum
jacktrades

80
@jacktrades: Jest to metoda niejawna, która istnieje tylko w kompilatorze. Dlatego klasa podstawowa nie może zadeklarować metody o tej samej nazwie, a zatem nie zostanie uwzględniona w automatycznie generowanym Javadocs. docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2
Torben

4
Dziwnie, jest to wspomniane w dokumentach valueOf ()
greg7gkb

129

Wszystkie stałe typu wyliczeniowego można uzyskać, wywołując public static T[] values()metodę niejawną tego typu:

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

@ RAnders00 Prawda. Ale wciąż odpowiedź jest poprawna, a format naprawdę nie ma znaczenia (przynajmniej dla mnie)
dARKpRINCE

Czego #zrobić?
YoTengoUnLCD

@YoTengoUnLCD Zasadniczo mówi, że wartości () są częścią obiektu Enum. np Enum#values()=Enum.values()
Reflektor

Hmm, przepraszam, nie podążam, czy to to samo, co używanie .(zawsze?)?
YoTengoUnLCD,

3
@YoTengoUnLCD Hashtag to składnia JavaDoc, a nie kod Java.
Jeff G

62

Możesz to zrobić w następujący sposób:

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

1
Pod warunkiem, że zaimportujesz java.util.EnumSet
Nate

8
Super przydatne dla pętli foreach Java8. EnumSet.allOf (Enum.class) .forEach (bla -> method (bla))
Hiro2k

1
@ Hiro2k Można również zrobić Arrays.stream(Enum.values()).forEach(...)- strumień będzie sekwencyjny
RAnders00

1
@ schatten dobrze, to setzamiast array. Nie jest to „lepsze”, chociaż moim zdaniem lepiej opisuje wartości wyliczeniowe, ponieważ z definicji zbioru wartości w zestawie nie mogą się powtarzać (jak w wyliczeniu), podczas gdy wartości w tablicy mogą być.
Jezor

2
@Jezor Jest to lepszy wybór, gdy naprawdę potrzebujesz bardzo szybkiego zestawu wyliczeń, takich jak flagi bitów, choć wydaje się to zbyt skomplikowane, aby można je było po prostu powtórzyć.
schatten

44

Strumienie

Przed Javą 8

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

Java 8

Możemy również korzystać z lambda i strumieni ( samouczek ):

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

Dlaczego forEachOrderedi nie forEachze strumieniami?

Zachowanie forEachjest wyraźnie niedeterministyczne, gdy jako forEachOrderedwykonuje akcję dla każdego elementu tego strumienia, w kolejności spotkań strumienia, jeśli strumień ma zdefiniowaną kolejność spotkań. Tak forEachnie gwarantuje, że zamówienie zostanie utrzymane.

Również podczas pracy ze strumieniami (szczególnie równoległymi) należy pamiętać o naturze strumieni. Zgodnie z dokumentem :

Wyniki potoku strumienia mogą być niedeterministyczne lub niepoprawne, jeśli parametry behawioralne operacji strumienia są stanowe. Stanowa lambda to taka, której wynik zależy od dowolnego stanu, który może się zmienić podczas wykonywania potoku strumienia.

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

Tutaj, jeśli operacja mapowania jest wykonywana równolegle, wyniki dla tego samego wejścia mogą się różnić w zależności od przebiegu, ze względu na różnice w szeregowaniu wątków, podczas gdy przy bezstanowym wyrażeniu lambda wyniki zawsze będą takie same.

Skutki uboczne parametrów behawioralnych podczas operacji strumieniowych są na ogół odradzane, ponieważ często mogą prowadzić do nieświadomego naruszenia wymogu bezpaństwowości, a także innych zagrożeń bezpieczeństwa wątków.

Strumienie mogą mieć określoną kolejność spotkań lub nie. To, czy strumień ma kolejność spotkań, zależy od operacji źródłowej i pośredniej.


Podobnie jak w przypadku wszystkich operacji przesyłania strumieniowego należy pamiętać o bezpaństwowości wątków i ograniczeniach skutków ubocznych docs.oracle.com/javase/8/docs/api/java/util/stream/… . Te dwie opcje iteracji wyliczeniowej różnią się znacznie pod tym względem.
buzz3791


19

Jeśli nie zależy ci na zamówieniu, powinno to działać:

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

2
Pod warunkiem, że importujesz java.util.EnumSet i java.util.Set
Nate

4
Z dokumentacji dlaEnumSet : Iterator zwrócony metodą iteratora przemierza elementy w ich naturalnym porządku (kolejność, w której deklarowane są stałe wyliczeniowe) . Gwarantuje to, że kolejność iteracji odpowiada kolejności zwróconej przez Enum.values().
Jeff G

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

5

Java8

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

z Java5 +

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

1
przepraszam. Właśnie zdałem sobie sprawę, że akhil_mittal już opublikował podobną odpowiedź.
Raghu K Nair

Kiedy i dlaczego powinienem używać Stream.of (o) .forEach? Pętla for wydaje się znacznie bardziej czytelna.
Jeremy

Nie, jeśli znasz programowanie funkcjonalne.
Alexis Dufrenoy,

5

Spróbuj użyć dla każdego

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

4

Więcej metod w java 8:

Korzystanie EnumSetzforEach

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

Korzystanie Arrays.asListzforEach

Arrays.asList(Direction.values()).forEach(...);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.