Eine 'for'-Schleife zum Durchlaufen einer Aufzählung in Java


Antworten:


1400

.values()

Sie können die values()Methode in Ihrer Enumeration aufrufen .

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

Diese values()Methode wird vom Compiler implizit deklariert . Es ist also nicht in Enumdoc aufgeführt.


43
Warum diese Methode values () nicht aufgeführt ist hier unter java.lang.Enum
jacktrades

80
@jacktrades: Dies ist eine implizite Methode, die nur im Compiler vorhanden ist. Daher kann die Basisklasse keine Methode mit demselben Namen deklarieren und wird daher nicht in die automatisch generierten Javadocs aufgenommen. docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2
Torben

4
Seltsamerweise wird es in den valueOf ()
-Dokumenten

129

Alle Konstanten eines Aufzählungstyps können durch Aufrufen der impliziten public static T[] values()Methode dieses Typs erhalten werden:

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

@ RAnders00 True. Aber immer noch ist die Antwort gültig und das Format spielt wirklich keine Rolle (zumindest für mich)
DARKpRINCE

Was macht das #?
YoTengoUnLCD

@YoTengoUnLCD Grundsätzlich heißt es, dass values ​​() Teil des Enum-Objekts ist. zB Enum#values()=Enum.values()
Spotlight

Hmm, es tut mir leid, ich folge nicht, ist es das gleiche wie mit .(immer?)?
YoTengoUnLCD

3
@YoTengoUnLCD Das Hashtag ist JavaDoc-Syntax, kein Java-Code.
Jeff G

62

Sie können dies wie folgt tun:

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

1
Vorausgesetzt, Sie importieren java.util.EnumSet
Nate

8
Super nützlich für Java8 foreach-Schleifen. EnumSet.allOf (Enum.class) .forEach (bla -> Methode (bla))
Hiro2k

1
@ Hiro2k Sie könnten auch tun Arrays.stream(Enum.values()).forEach(...)- der Stream wird sequentiell sein
RAnders00

1
@schatten gut, es ist ein setstatt array. Es ist nicht "besser", obwohl es meiner Meinung nach Aufzählungswerte besser beschreibt, da nach der Definition von set Werte in set nicht wiederholt werden können (wie in enum), wohingegen Werte in Array sein können.
Jezor

2
@Jezor Es ist eine bessere Wahl, wenn Sie tatsächlich einen sehr schnellen Satz von Aufzählungen wie Bit-Flags benötigen, obwohl dies für eine einfache Iteration zu kompliziert zu sein scheint.
schatten

44

Streams

Vor Java 8

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

Java 8

Wir können auch Lambda und Streams verwenden ( Tutorial ):

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

Warum forEachOrderedund nicht forEachmit Streams?

Das Verhalten von forEachist explizit nicht deterministisch, wenn der forEachOrderedBenutzer eine Aktion für jedes Element dieses Streams in der Begegnungsreihenfolge des Streams ausführt, wenn der Stream eine definierte Begegnungsreihenfolge hat. DamitforEach garantiert nicht , dass die Reihenfolge gehalten werden würde.

Beachten Sie auch bei der Arbeit mit Streams (insbesondere parallelen) die Art der Streams. Nach dem Dokument :

Die Ergebnisse der Stream-Pipeline sind möglicherweise nicht deterministisch oder falsch, wenn die Verhaltensparameter für die Stream-Operationen statusbehaftet sind. Ein Stateful Lambda ist eines, dessen Ergebnis von jedem Zustand abhängt, der sich während der Ausführung der Stream-Pipeline ändern kann.

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

Wenn hier die Zuordnungsoperation parallel ausgeführt wird, können die Ergebnisse für dieselbe Eingabe aufgrund von Unterschieden bei der Thread-Planung von Lauf zu Lauf variieren, während bei einem zustandslosen Lambda-Ausdruck die Ergebnisse immer dieselben wären.

Nebenwirkungen von Verhaltensparametern bei Stream-Vorgängen werden im Allgemeinen nicht empfohlen, da sie häufig zu unwissentlichen Verstößen gegen die Anforderung der Staatenlosigkeit sowie zu anderen Sicherheitsrisiken für Threads führen können.

Streams können eine definierte Begegnungsreihenfolge haben oder nicht. Ob ein Stream eine Begegnungsreihenfolge hat oder nicht, hängt von der Quelle und den Zwischenoperationen ab.


Wie bei allen Stream-Vorgängen sollten Sie sich der Statuslosigkeit des Threads und der Einschränkungen für Nebenwirkungen bewusst sein . Docs.oracle.com/javase/8/docs/api/java/util/stream/… . Diese 2 Aufzählungsiterationsoptionen unterscheiden sich in dieser Hinsicht erheblich.
Buzz3791


19

Wenn Sie sich nicht für die Reihenfolge interessieren, sollte dies funktionieren:

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

2
Vorausgesetzt, Sie importieren java.util.EnumSet und java.util.Set
Nate

4
Aus der Dokumentation fürEnumSet : Der von der Iterator-Methode zurückgegebene Iterator durchläuft die Elemente in ihrer natürlichen Reihenfolge (der Reihenfolge, in der die Enum-Konstanten deklariert werden) . Dies garantiert, dass die Reihenfolge der Iteration mit der von zurückgegebenen Reihenfolge übereinstimmt Enum.values().
Jeff G

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

5

Java8

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

von Java5 +

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

1
Oh, das tut mir leid. Ich habe gerade festgestellt, dass akhil_mittal bereits die ähnliche Antwort gepostet hat.
Raghu K Nair

Wann und warum sollte ich Stream.of (o) .forEach verwenden? Die for-Schleife scheint viel besser lesbar zu sein.
Jeremy

Nicht, wenn Sie mit funktionaler Programmierung vertraut sind.
Alexis Dufrenoy

5

Versuchen Sie, jeweils einen zu verwenden

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

4

Weitere Methoden in Java 8:

Verwenden EnumSetmitforEach

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

Verwenden Arrays.asListmitforEach

Arrays.asList(Direction.values()).forEach(...);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.