945 Stimmen

Eine 'for'-Schleife zur Iteration über eine Aufzählung in Java

Ich habe eine enum in Java für die Kardinal- und Zwischenrichtungen:

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

Wie kann ich eine for Schleife, die jeden dieser Punkte durchläuft enum Werte?

0 Stimmen

1487voto

notnoop Punkte 57727

.values()

Sie können die values() Methode für Ihre Aufzählung.

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

Ce site values() Methode ist implizit durch den Compiler deklariert . Es ist also nicht aufgeführt auf Enum doc.

46 Stimmen

Warum diese Methode Werte() ist nicht aufgelistet aquí unter java.lang.enum

83 Stimmen

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

4 Stimmen

Merkwürdigerweise wird sie in der valueOf()-Dokumente

141voto

dfa Punkte 110809

Alle Konstanten eines Enum-Typs können durch den Aufruf der impliziten public static T[] values() Methode dieses Typs:

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

0 Stimmen

@RAnders00 Stimmt. Aber die Antwort ist trotzdem gültig und das Format ist wirklich egal (zumindest für mich)

0 Stimmen

Was bedeutet die # tun?

0 Stimmen

@YoTengoUnLCD Im Grunde heißt es, dass values() Teil des Enum-Objekts ist. z.B. Enum#values() = Enum.values()

64voto

toluju Punkte 4027

Sie können dies wie folgt tun:

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

2 Stimmen

Vorausgesetzt, Sie importieren java.util.EnumSet

9 Stimmen

Sehr nützlich für Java8 foreach-Schleifen. EnumSet.allOf(Enum.class).forEach(blah -> method(blah))

1 Stimmen

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

47voto

akhil_mittal Punkte 20953

Ströme

Vor Java 8

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

Java 8

Wir können auch lambda und Streams verwenden ( Anleitung ):

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

Warum forEachOrdered und nicht forEach mit Strömen ?

Das Verhalten von forEach explizit nicht-deterministisch ist, während die forEachOrdered führt für jedes Element dieses Datenstroms eine Aktion aus, und zwar in der Reihenfolge der Begegnungen, wenn der Datenstrom eine bestimmte Reihenfolge der Begegnungen hat. Also forEach garantiert nicht, dass der Auftrag ausgeführt wird.

Auch bei der Arbeit mit Datenströmen (insbesondere parallelen) ist die Natur von Datenströmen zu beachten. Gemäß der doc :

Die Ergebnisse von Stream-Pipelines können nicht deterministisch oder falsch sein, wenn die Verhaltensparameter der Stream-Operationen zustandsabhängig sind. Ein zustandsabhängiges Lambda ist ein Lambda, dessen Ergebnis von einem 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; })...

Wird die Mapping-Operation parallel durchgeführt, können die Ergebnisse für dieselbe Eingabe aufgrund von Unterschieden in der Thread-Planung von Lauf zu Lauf variieren, wohingegen die Ergebnisse bei einem zustandslosen Lambda-Ausdruck immer die gleichen sind.

Von Seiteneffekten in Verhaltensparametern für Stream-Operationen wird im Allgemeinen abgeraten, da sie oft zu unwissentlichen Verstößen gegen die Anforderung der Zustandslosigkeit sowie zu anderen Gefahren für die Thread-Sicherheit führen können.

Ströme können eine bestimmte Reihenfolge der Begegnungen haben, müssen es aber nicht. Ob ein Datenstrom eine Begegnungsreihenfolge hat oder nicht, hängt von der Quelle und den Zwischenoperationen ab.

2 Stimmen

Wie bei allen Stream-Operationen sind die Grenzen der Thread-Statuslosigkeit und der Nebeneffekte zu beachten docs.oracle.com/javase/8/docs/api/java/util/stream/ . Diese beiden Aufzählungsoptionen unterscheiden sich in dieser Hinsicht erheblich.

21voto

Tom Jefferys Punkte 12955

Wenn Sie sich nicht um die Reihenfolge kümmern, sollte das funktionieren:

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

2 Stimmen

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

4 Stimmen

Desde el Dokumentation für EnumSet : Der Iterator, der von der Iterator-Methode zurückgegeben wird, durchläuft die Elemente in ihrer natürliche Ordnung (die Reihenfolge, in der die Enum-Konstanten deklariert werden) . Dies garantiert, dass die Reihenfolge der Iteration mit der Reihenfolge übereinstimmt, die von Enum.values() .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X