A 'for' loop untuk beralih pada enum di Jawa


Jawaban:


1400

.values()

Anda dapat memanggil values()metode pada enum Anda.

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

Ini values()metode ini secara implisit dinyatakan oleh compiler . Jadi tidak terdaftar di Enumdoc.


43
Mengapa nilai metode ini () tidak tercantum di sini di bawah java.lang.enum
jacktrades

80
@jacktrades: Ini adalah metode implisit yang hanya ada di kompiler. Oleh karena itu kelas dasar tidak dapat mendeklarasikan metode dengan nama yang sama dan karenanya tidak disertakan dalam Javadocs yang dibuat secara otomatis. docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2
Torben

4
Anehnya, ini disebutkan dalam valueOf () docs
greg7gkb

129

Semua konstanta dari tipe enum dapat diperoleh dengan memanggil public static T[] values()metode implisit dari tipe itu:

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

@ RAnders00 Benar. Tapi tetap saja jawabannya valid dan formatnya benar-benar tidak masalah (minimal bagi saya)
dARKpRINCE

Apa yang #dilakukan?
YoTengoUnLCD

@YoTengoUnLCD Pada dasarnya ini mengatakan bahwa nilai () adalah bagian dari objek Enum. misalnya Enum#values()=Enum.values()
Spotlight

Hmm, maaf, saya tidak mengikuti, apakah sama dengan menggunakan .(selalu?)?
YoTengoUnLCD

3
@YoTengoUnLCD Tagar adalah sintaks JavaDoc, bukan kode Java.
Jeff G

62

Anda dapat melakukan ini sebagai berikut:

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

1
Asalkan Anda mengimpor java.util.EnumSet
Nate

8
Super berguna untuk Java8 foreach loop. EnumSet.allOf (Enum.class) .forEach (bla -> method (bla))
Hiro2k

1
@ Hiro2k Anda juga bisa melakukannya Arrays.stream(Enum.values()).forEach(...)- alirannya akan berurutan
RAnders00

1
@schatten yah, ini setbukan array. Ini bukan "lebih baik", meskipun itu menggambarkan nilai enum lebih baik menurut saya, karena dari definisi set, nilai-nilai dalam set tidak dapat diulangi (seperti dalam enum), sedangkan nilai-nilai dalam array dapat.
Jezor

2
@Jezor Ini adalah pilihan yang lebih baik ketika Anda benar-benar membutuhkan set enum yang sangat cepat, seperti bendera bit, meskipun tampaknya terlalu rumit untuk iterasi sederhana.
schatten

44

Streaming

Sebelum ke Jawa 8

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

Java 8

Kami juga dapat menggunakan lambda dan stream ( Tutorial ):

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

Kenapa forEachOrdereddan tidakforEach dengan stream?

Perilaku forEacheksplisit nondeterministik di mana sebagai forEachOrderedmelakukan tindakan untuk setiap elemen aliran ini, dalam urutan pertemuan aliran jika aliran memiliki urutan pertemuan yang ditentukan. Jadi forEachtidak menjamin bahwa pesanan akan disimpan.

Juga ketika bekerja dengan stream (terutama yang paralel) perlu diingat sifat stream. Sesuai dokumen :

Hasil aliran pipa mungkin tidak deterministik atau salah jika parameter perilaku ke operasi aliran stateful. Lambda stateful adalah salah satu yang hasilnya tergantung pada negara yang mungkin berubah selama pelaksanaan pipa aliran.

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

Di sini, jika operasi pemetaan dilakukan secara paralel, hasil untuk input yang sama dapat bervariasi dari satu menjalankan ke menjalankan, karena perbedaan penjadwalan thread, sedangkan, dengan ekspresi lambda stateless, hasilnya akan selalu sama.

Efek samping dalam parameter perilaku untuk mengalirkan operasi, secara umum, tidak disarankan, karena seringkali dapat menyebabkan pelanggaran tanpa disadari terhadap persyaratan kewarganegaraan, serta bahaya keselamatan benang lainnya.

Streaming mungkin atau mungkin tidak memiliki urutan pertemuan yang ditentukan. Apakah aliran memiliki urutan pertemuan atau tidak tergantung pada sumber dan operasi perantara.


Seperti halnya semua operasi streaming, sadari kewarganegaraan utas dan batas efek samping, docs.oracle.com/javase/8/docs/api/java/util/stream/… . Kedua opsi iterasi ini berbeda secara signifikan dalam hal ini.
buzz3791


19

Jika Anda tidak peduli dengan pesanan ini, ini akan berfungsi:

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

2
Asalkan Anda mengimpor java.util.EnumSet dan java.util.Set
Nate

4
Dari dokumentasi untukEnumSet : Iterator yang dikembalikan oleh metode iterator melintasi elemen dalam tatanan alami mereka (urutan di mana konstanta enum dinyatakan) . Ini menjamin bahwa urutan iterasi cocok dengan pesanan yang dikembalikan oleh Enum.values().
Jeff G

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

5

Java8

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

dari Java5 +

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

1
Oh maaf. Saya baru menyadari bahwa akhil_mittal sudah memposting jawaban yang sama.
Raghu K Nair

Kapan dan mengapa saya harus menggunakan Stream.of (o) .forEach? Untuk loop tampaknya jauh lebih mudah dibaca.
Jeremy

Tidak jika Anda terbiasa dengan pemrograman fungsional.
Alexis Dufrenoy

5

Cobalah untuk menggunakan masing-masing

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

4

Lebih banyak metode di java 8:

Menggunakan EnumSetdenganforEach

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

Menggunakan Arrays.asListdenganforEach

Arrays.asList(Direction.values()).forEach(...);
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.