Mam enumJava w kierunkach głównych i pośrednich:
public enum Direction {
NORTH,
NORTHEAST,
EAST,
SOUTHEAST,
SOUTH,
SOUTHWEST,
WEST,
NORTHWEST
}
Jak napisać
forpętlę, która iteruje każdą z tychenumwartości?
Mam enumJava w kierunkach głównych i pośrednich:
public enum Direction {
NORTH,
NORTHEAST,
EAST,
SOUTHEAST,
SOUTH,
SOUTHWEST,
WEST,
NORTHWEST
}
Jak napisać
forpętlę, która iteruje każdą z tychenumwartoś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 Enumdokumencie.
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
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ć.
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 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.
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);
}