Mam enum
Java w kierunkach głównych i pośrednich:
public enum Direction {
NORTH,
NORTHEAST,
EAST,
SOUTHEAST,
SOUTH,
SOUTHWEST,
WEST,
NORTHWEST
}
Jak napisać
for
pętlę, która iteruje każdą z tychenum
wartości?
Mam enum
Java w kierunkach głównych i pośrednich:
public enum Direction {
NORTH,
NORTHEAST,
EAST,
SOUTHEAST,
SOUTH,
SOUTHWEST,
WEST,
NORTHWEST
}
Jak napisać
for
pętlę, która iteruje każdą z tychenum
wartości?
Odpowiedzi:
.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 Enum
dokumencie.
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);
}
#
zrobić?
Enum#values()
=Enum.values()
.
(zawsze?)?
Możesz to zrobić w następujący sposób:
for (Direction direction : EnumSet.allOf(Direction.class)) {
// do stuff
}
Arrays.stream(Enum.values()).forEach(...)
- strumień będzie sekwencyjny
set
zamiast 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ć.
for (Direction dir : Direction.values()) {
System.out.println(dir);
}
Możemy również korzystać z lambda i strumieni ( samouczek ):
Stream.of(Direction.values()).forEachOrdered(System.out::println);
Dlaczego forEachOrdered
i nie forEach
ze strumieniami?
Zachowanie forEach
jest wyraźnie niedeterministyczne, gdy jako forEachOrdered
wykonuje akcję dla każdego elementu tego strumienia, w kolejności spotkań strumienia, jeśli strumień ma zdefiniowaną kolejność spotkań. Tak forEach
nie 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.
for(Direction dir : Direction.values())
{
}
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
}
EnumSet
: 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()
.
Java8
Stream.of(Direction.values()).forEach(System.out::println);
z Java5 +
for ( Direction d: Direction.values()){
System.out.println(d);
}