2012-08-06 44 views
49

Tôi có ví dụ sau:EnumSet thực sự có ý nghĩa gì?

import java.util.EnumSet; 
import java.util.Iterator; 

public class SizeSet { 

    public static void main(String[] args) { 
     EnumSet largeSize = EnumSet.of(Size.XL,Size.XXL,Size.XXXL); 
     for(Iterator it = largeSize.iterator();it.hasNext();){ 
      Size size = (Size)it.next(); 
      System.out.println(size); 
     } 
    } 
} 


enum Size { 
    S, M, L, XL, XXL, XXXL; 

} 

Trong mã này, tôi có thể hiểu rằng Enum tạo ra một kiểu Enum của kích cỡ.

Câu hỏi của tôi là: là largeSize một đối tượng của kiểu EnumSet? Điều đó thực sự có ý nghĩa gì? Tôi thực sự muốn hiểu nó tốt hơn.

Trả lời

28

Đối với bất kỳ biến, kiểu của nó được tìm thấy trong khai của nó:

EnumSet largeSize 

Vì vậy, có, largeSize (mà nên được đặt tên là largeSizes vì nó là một bộ sưu tập) là loại EnumSet. Cũng cần phải generified, và do đó được khai báo là

EnumSet<Size> largeSizes 

gì nó có nghĩa là, là largeSizes là loại EnumSet. An EnumSet là một Set có chứa cá thể enum của loại enum cụ thể, theo cách hiệu quả hơn các triển khai Set khác (như HashSet, TreeSet, v.v.). Để biết số EnumSet là gì, hãy đọc số API.

+0

Vậy đó là loại Enum trong Enum? có nghĩa là một đối tượng khác (largeSizes) đại diện cho một phần của một đối tượng (Kích thước)? – Adam

+2

Không, đó là một tập hợp các giá trị enum. 'largeSizes' là tập hợp chứa XL, XXL và XXXL. Bạn có thể thay thế nó bằng một HashSet, và nó sẽ không thay đổi bất cứ điều gì ngoại trừ hiệu suất và mức tiêu thụ bộ nhớ. 'Kích thước' không phải là một đối tượng. Đó là một lớp học. Và lớp này định nghĩa một số hằng số: L, XL, XXL, vv của loại 'Kích thước'. –

+0

Tôi đã không hiểu rõ nó ... nếu Kích thước (nên kích thước) là một đối tượng tại sao nó không giống như: Enum Sizes = new Enum; ? và sau đó 3 dòng cuối cùng trong mã đầu tiên? Nếu tôi có thể tạo một đối tượng kích thước 'Kích thước', nghĩa là Kích thước phải là một Lớp .... – Adam

3

Với ví dụ sau:

.... 
public static final String S = "s"; 
public static final String M = "m"; 
public static final String L = "l"; 
.... 

Set<String> sizeSet = new HashSet<String>(); 
sizeSet.add(S); 
sizeSet.add(M); 

vậy, sizeSet ​​là những gì trong ví dụ trên?

EnumSet không có gì khác biệt so với ví dụ trên, chỉ EnumSet là một cài đặt Bộ đặc biệt hoạt động và tối ưu hóa với các loại enum, đó là tất cả.

34

Đơn giản hóa mã của bạn

EnumSet<Size> largeSize = EnumSet.of(Size.XXXL, Size.XXL, Size.XL, Size.L); 
for(Size size: largeSize) 
    System.out.print(size+" "); 

Bạn có thể thấy rằng largeSize là một Set thường ngoại trừ nó được thiết kế để lưu trữ Enums. Làm thế nào là khác nhau? Thứ nhất, JVM biết tất cả các giá trị có thể có của tập hợp có nghĩa là thay vì lưu trữ tất cả các đối tượng, nó có thể sử dụng bitmap trong đó 1 có nghĩa là mặt hàng hiện tại và 0 có nghĩa là nó không có. Điều này cũng có nghĩa là thứ tự của tập hợp là thứ tự của các giá trị thứ tự tức là thứ tự chúng được xác định. Đây là lý do tại sao điều này in

L XL XXL XXXL 

Nếu bạn muốn biết thêm chi tiết Tôi khuyên bạn nên đọc nguồn cho lớp này.

-2

Nó nhanh chóng biến bất kỳ thành phần Enum nào thành bộ, EnumSet là một loại Tập hợp khác.

public enum Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH } 

EnumSet.of(Style.BOLD, Style.ITALIC); 
7

EnumSet được sử dụng cụ thể để lưu trữ phần tử kiểu enum và lặp lại nhanh chóng. Ví dụ:

for (Day d : EnumSet.range(Day.MONDAY, Day.FRIDAY)) 
     System.out.println(d); 

Đoạn mã trên sẽ hiển thị các ngày trong tuần từ thứ Hai đến thứ Sáu.

3

Theo Oracle doc

bộ Enum được đại diện trong nội bộ như vectơ bit.Biểu diễn này cực kỳ nhỏ gọn và hiệu quả.

Có thể đọc, nhập an toàn, dấu chân bộ nhớ thấp ... Bạn muốn gì hơn?

23

Một đơn giản Enum là danh sách các giá trị mà bạn chỉ có thể chọn một từ một thời điểm. Sử dụng ví dụ của bạn, một kích thước có thể chỉ là một trong S, M, L, vv cho bất kỳ loại vải cụ thể nào. Bạn có thể sử dụng hằng số đơn giản thay vì Enum nhưng điều này có lợi thế về khả năng đọc, bảo trì dễ dàng hơn và kiểm tra loại nghiêm ngặt.

An EnumSet sẽ được sử dụng khi bạn cần biến để giả định nhiều hơn một giá trị Enum cùng một lúc. Ví dụ: phông chữ bạn viết trên màn hình có thể là cả hai hình ảnh đậmin nghiêng cùng một lúc. An EnumSet sẽ cho phép bạn thêm các giá trị khác nhau và để kiểm tra xem một trong các giá trị đó có thực sự được đặt ở bất kỳ thời điểm đã định nào không. Nếu bạn đã đến Java từ các ngôn ngữ lập trình khác, đây là chức năng thường được gọi là cờ.

So sánh hai:

enum Size { S, M, L, XL, XXL, XXXL } 
Size currentSize; 
... 
currentSize = Size.S; 
... 
if (currentSize == Size.S) ... 

định nghĩa, chuyển nhượng và sau đó kiểm tra cho một giá trị duy nhất Enum.

enum FontStyle { Bold, Italic, Underline, Strikethrough } 
EnumSet<FontStyle> currentStyle; 
... 
currentStyle = EnumSet.of(FontStyle.Bold, FontStyle.Italic); 
... 
if (currentStyle.contains(FontStyle.Italic)) ... 

xác định, chỉ định hai giá trị Enum cùng một lúc, sau đó kiểm tra xem một trong số đó có thực sự được đặt hay không.

3
EnumSet largeSize 

EnumSet largeSize là tập hợp các giá trị Enum chứa XL, XXL và XXXL.

Size 

Kích thước là một loại kiểu Enum có giá trị không đổi S, M, L, XL, XXL, XXXL.

largeSize.iterator() 

Iterator cho EnumSet theo thứ tự tự nhiên, thứ tự mà giá trị của enum được khai báo ban đầu.

  • Lớp EnumSet là thành viên của Khung sưu tập Java & không được đồng bộ hóa.
  • Việc triển khai bộ hiệu suất cao, chúng nhanh hơn nhiều so với HashSet.
  • Tất cả các thành phần của mỗi cá thể EnumSet phải là các thành phần của một loại enum .

Để Biết thêm đọc api doc: http://docs.oracle.com/javase/8/docs/api/java/util/EnumSet.html

6

Từ cuốn sách Joshua Bloch của bản thân và bằng lời nói của mình:

Gói java.util cung cấp lớp EnumSet để đại diện cho một cách hiệu quả bộ các giá trị được rút ra từ một loại enum duy nhất. Lớp này triển khai giao diện Set, cung cấp tất cả tính phong phú, kiểu an toàn và khả năng tương tác mà bạn nhận được với bất kỳ triển khai Set nào khác.Nhưng nội bộ, mỗi EnumSet được biểu diễn dưới dạng bit bit. Nếu loại enum cơ bản có sáu mươi bốn hoặc ít hơn các yếu tố - và hầu hết làm - toàn bộ EnumSet được biểu diễn bằng một lần duy nhất, do đó hiệu suất của nó có thể so sánh với một trường bit. Hoạt động hàng loạt, chẳng hạn như removeAll và retainAll, được triển khai bằng bit số khôn ngoan, giống như bạn sẽ làm theo cách thủ công cho các trường bit. Nhưng bạn được cách nhiệt từ sự xấu xí và sự sai lệch về lỗi của bit thủ công twiddling. EnumSet thực hiện công việc khó khăn cho bạn.

Vì vậy, chúng tôi có thể làm điều gì đó như thế này.

public class SizeSet { 

    public enum Size {S, M, L, XL, XXL, XXXL} 

    public void applySize(Set<Size> sizes){} 

} 

Khách hàng Mã gọi đó là có thể làm điều gì đó như

SizeSet largeSizeSet = new SizeSet(); 
largeSizeSet.applySize(EnumSet.of(Size.L, Size.XXL, Size.XXL)); 

Lưu ý rằng phương pháp applySize lấy Set<Size> chứ không phải là một EnumSet<Size>. Trong khi nó là khá rõ ràng và có khả năng là khách hàng sẽ vượt qua một EnumSet để phương pháp, nó là một thực hành tốt để chấp nhận một giao diện hơn là thực hiện cụ thể.

Các vấn đề liên quan