2012-08-06 92 views
49

我有以下示例:EnumSet的真正含義是什麼?

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; 

} 

在此代碼我可以理解的是,枚舉創建一個枚舉類型尺寸。

我的問題是:是largeSize EnumSet類型的一個對象?這是什麼意思?我真的想更好地理解它。

回答

28

對於任何一個變量,它的類型是在它的聲明中發現:

EnumSet largeSize 

所以,是的,largeSize(這應該被命名爲largeSizes,因爲它是一個集合)是EnumSet型。還應當泛型,因而被宣佈爲

EnumSet<Size> largeSizes 

這意味着什麼,是largeSizesEnumSet型。 EnumSet是一個Set,其中包含特定枚舉類型的枚舉實例,比其他Set實現(例如HashSet,TreeSet等)更有效。要知道什麼是EnumSet,請閱讀其API

+0

所以這是Enum裏面的枚舉?意味着代表對象(尺寸)的一部分的另一個對象(largeSizes)? – Adam 2012-08-06 09:15:59

+2

不,這是一組枚舉值。 'largeSizes'是一個包含XL,XXL和XXXL的集合。你可以用HashSet替換它,除了性能和內存消耗之外,它不會改變任何東西。 「大小」不是一個對象。這是一堂課。這個類定義了幾個常量:L,XL,XXL等'Size'類型。 – 2012-08-06 09:18:52

+0

我沒有很好地理解它......如果Size(應該是Sizes)是一個爲什麼它看起來不是這樣的對象:Enum Sizes = new Enum; ?然後在第一個代碼中的最後3行?如果我可以製作「尺寸」的「尺寸」對象,則表示尺寸應該是一個類別.... – Adam 2012-08-06 09:33:32

3

考慮下面的例子:

.... 
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); 

那麼,什麼是sizeSet在上面的例子?

EnumSet與上面的例子沒什麼不同,只是EnumSet是一個特殊的Set實現,它與枚舉類型一起工作並進行了優化,就這些了。

34

簡化你的代碼

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

你可以看到largeSize是一個普通的設置除了它設計用來存儲枚舉。這有什麼不同?首先,JVM知道集合的所有可能值,這意味着不用存儲所有可以使用位圖的對象,其中1表示項目存在,0表示不存在。這也意味着該集合的順序是順序值的順序,即它們被定義的順序。這就是爲什麼這打印

L XL XXL XXXL 

如果你想知道更多的細節,我建議你閱讀本課程的源代碼。

-2

它可以快速將任何Enum元素轉換爲集合,EnumSet是另一種類型的Set。

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

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

EnumSet專門用於存儲枚舉類型元素並快速迭代它。例如,

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

上面的代碼片段將顯示從星期一到星期五的星期幾。

3

根據Oracle doc

枚舉套在內部表示爲位向量。這種表示非常緊湊和高效。

可讀,類型安全,內存佔用少...您還需要什麼?

23

簡單的Enum是一個值列表,您一次只能選擇一個。使用你的例子,對於任何給定的布,尺寸只能是S,M,L等中的一個。您可以使用簡單的常量而不是Enum,但這具有易讀性,易維護和嚴格類型檢查的優點。

當您需要變量同時假定多個Enum值時,將使用EnumSet。例如,您要寫屏幕的字體可以同時爲加粗斜體EnumSet將允許您添加各種值並測試是否在給定時間內實際設置了其中一個值。如果您從其他編程語言來到Java,這是通常稱爲標誌的功能。

比較兩個:

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

限定,受讓人和然後檢查單個Enum值。

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

限定,同時分配2個Enum值,然後檢查那些中的一個是否被實際設定與否。

3
EnumSet largeSize 

EnumSet largeSize是一組包含XL,XXL和XXXL的Enum值。

Size 

大小是一類Enum類型,常數值爲S,M,L,XL,XXL,XXXL。

largeSize.iterator() 

爲EnumSet迭代器是自然順序,其中枚舉值最初聲明的順序。

  • EnumSet類是Java Collections Framework的成員&未同步。
  • 它是一個高性能的集合實現,它們比HashSet要快得多。
  • 每個EnumSet實例的所有元素都必須是單枚舉類型的一個 的元素。

知道更多閱讀API文檔:http://docs.oracle.com/javase/8/docs/api/java/util/EnumSet.html

6

從約書亞布洛赫的書本身和他自己的話:

java.util包中提供了EnumSet類高效地表示 套從單個枚舉類型中繪製的值。該類實現了Set接口的 ,提供了與任何其他Set實現一起獲得的所有豐富性,類型安全性和 互操作性。但是在內部,每個EnumSet表示爲一個位向量。如果 下面的枚舉類型具有64個或更少的元素 - 並且大多數是 - 整個EnumSet用單個long表示,所以它的性能與位域的性能相當。批量操作, ,如removeAll和retainAll,都是使用位運算來實現的,就像您手動執行位域一樣。但你是 絕緣手動位 twiddling的醜陋和錯誤傾向性。 EnumSet爲你做了很多努力。

所以我們可以這樣做。

public class SizeSet { 

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

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

} 

客戶端代碼調用它可能像做

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

注意,applySize方法將Set<Size>而非EnumSet<Size>。雖然很明顯,並且很可能客戶端會將EnumSet傳遞給方法,但接受接口而不是具體實現是一種很好的做法。

相關問題