Một vòng lặp 'for' để lặp lại một enum trong Java


Câu trả lời:


1400

.values()

Bạn có thể gọi values()phương thức trên enum của bạn.

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

Đây values()là phương pháp được ngầm tuyên bố bởi trình biên dịch . Vì vậy, nó không được liệt kê trên Enumdoc.


43
Tại sao giá trị phương thức này () không được liệt kê ở đây theo java.lang.enum
jacktrades

80
@jacktrades: Đây là một phương thức ngầm chỉ tồn tại trong trình biên dịch. Do đó, lớp cơ sở không thể khai báo một phương thức có cùng tên và do đó nó không được bao gồm trong Javadocs được tạo tự động. docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2
Torben

4
Điều kỳ lạ, nó được đề cập trong các tài liệu valueOf ()
greg7gkb

129

Tất cả các hằng số của một loại enum có thể thu được bằng cách gọi public static T[] values()phương thức ngầm định của loại đó:

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

@ RAnders00 Đúng. Nhưng câu trả lời vẫn hợp lệ và định dạng thực sự không quan trọng (ít nhất là với tôi)
dARKpRINCE 8/2/2016

Làm gì #?
YoTengoUnLCD

@YoTengoUnLCD Về cơ bản, nó nói rằng các giá trị () là một phần của đối tượng Enum. ví dụ Enum#values()=Enum.values()
Tiêu điểm

Hmm, tôi xin lỗi, tôi không làm theo, nó có giống như sử dụng .(luôn luôn không?)?
YoTengoUnLCD

3
@YoTengoUnLCD Hashtag là cú pháp JavaDoc, không phải mã Java.
Jeff G

62

Bạn có thể làm điều này như sau:

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

1
Với điều kiện bạn nhập java.util.Enumset
Nate

8
Siêu hữu ích cho các vòng lặp foreach Java8. EnumSet.allOf (Enum. Class) .forEach (blah -> phương thức (blah))
Hiro2k

1
@ Hiro2k Bạn cũng có thể làm Arrays.stream(Enum.values()).forEach(...)- luồng sẽ tuần tự
RAnders00

1
@schatten tốt, đó là một setthay vì array. Theo ý kiến ​​của tôi thì nó không "tốt hơn", mặc dù nó mô tả các giá trị enum tốt hơn, bởi vì từ định nghĩa của tập hợp, các giá trị trong tập hợp không thể được lặp lại (như trong enum), trong khi các giá trị trong mảng có thể.
Jezor

2
@Jezor Đó là một lựa chọn tốt hơn khi bạn thực sự cần một bộ enum rất nhanh, như cờ bit, mặc dù dường như quá phức tạp cho một lần lặp đơn giản.
schatten

44

Dòng

Trước Java 8

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

Java 8

Chúng tôi cũng có thể sử dụng lambda và stream ( Hướng dẫn ):

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

Tại sao forEachOrderedvà không forEachvới luồng?

Hành vi của forEachrõ ràng là không đặc biệt khi forEachOrderedthực hiện một hành động cho từng thành phần của luồng này, theo thứ tự bắt gặp của luồng nếu luồng có thứ tự bắt gặp được xác định. Vì vậy, forEachkhông đảm bảo rằng thứ tự sẽ được giữ.

Ngoài ra khi làm việc với các luồng (đặc biệt là các luồng song song) hãy ghi nhớ bản chất của các luồng. Theo tài liệu :

Kết quả đường ống dòng có thể không xác định hoặc không chính xác nếu các tham số hành vi cho các hoạt động luồng là trạng thái. Một lambda trạng thái là một kết quả phụ thuộc vào bất kỳ trạng thái nào có thể thay đổi trong quá trình thực hiện đường ống truyền phát.

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

Ở đây, nếu hoạt động ánh xạ được thực hiện song song, kết quả cho cùng một đầu vào có thể thay đổi từ chạy sang chạy, do sự khác biệt về lập lịch của luồng, trong khi đó, với biểu thức lambda không trạng thái, kết quả sẽ luôn giống nhau.

Nhìn chung, các tác dụng phụ trong các tham số hành vi đối với các hoạt động truyền phát, không được khuyến khích, vì chúng thường có thể dẫn đến việc vô tình vi phạm yêu cầu không trạng thái, cũng như các nguy cơ về an toàn luồng khác.

Các luồng có thể có hoặc không có thứ tự bắt gặp được xác định. Việc một luồng có thứ tự gặp hay không phụ thuộc vào nguồn và các hoạt động trung gian.


Như với tất cả các hoạt động truyền phát, hãy chú ý đến trạng thái không trạng thái của luồng và giới hạn tác dụng phụ docs.oracle.com/javase/8/docs/api/java/util/stream/ . Hai tùy chọn lặp enum khác nhau đáng kể về vấn đề này.
buzz3791


19

Nếu bạn không quan tâm đến thứ tự thì nó sẽ hoạt động:

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

2
Cung cấp cho bạn nhập java.util.EnumSet và java.util.Set
Nate

4
Từ tài liệu choEnumSet : Trình lặp được trả về bởi phương thức iterator đi ngang qua các phần tử theo thứ tự tự nhiên của chúng (thứ tự mà các hằng số enum được khai báo) . Điều này đảm bảo rằng thứ tự lặp lại khớp với thứ tự được trả về Enum.values().
Jeff G

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

5

Java8

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

từ Java5 +

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

1
ồ xin lỗi. Tôi mới nhận ra rằng akhil_mittal đã đăng câu trả lời tương tự.
Raghu K Nair

Khi nào và tại sao tôi nên sử dụng Stream.of (o) .forEach? Vòng lặp for có vẻ dễ đọc hơn nhiều.
Jeremy

Không nếu bạn quen thuộc với lập trình chức năng.
Alexis Dufrenoy

5

Cố gắng sử dụng một cho mỗi

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

4

Các phương thức khác trong java 8:

Sử dụng EnumSetvớiforEach

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

Sử dụng Arrays.asListvớiforEach

Arrays.asList(Direction.values()).forEach(...);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.