2013-05-16 107 views
3

我有一個接口使用枚舉的EnumSet實現接口

public interface TerminalSymbol { 
    // methods ... 
} 

枚舉

// common usage enum that I need 
public enum Common implements TerminalSymbol { 
    EPSILON; 

    @Override 
    // methods ... 
} 

,我想這樣做:

enum Term implements TerminalSymbol { 
    A, B, C, ... 

    @Override 
    // methods ... 
} 

EnumSet<? extends TerminalSymbol> terminalSymbols = EnumSet.allOf(Term.class); 
terminalSymbol.add(Common.EPSILON); // this line gives me error 

和錯誤是(在我的情況下):

The method add(capture#1-of ? extends TerminalSymbol) in the type AbstractCollection<capture#1-of ? extends TerminalSymbol> is not applicable for the arguments (Common) 

現在我知道如果我使用Set<SomeInterface>我可以防止這種類型的錯誤(並且我可以繼續開發我的課程,代表正式的語法),但我想使用EnumSet,因爲它可能比HashSet。我怎麼解決這個問題?

+0

您試圖使用'EnumSet'而不是'HashSet',或者僅僅是爲了使用'EnumSet',它真的是非常關鍵的效率明智嗎?泛型聰明,它最終看起來像是試圖創建一些堆污染,因爲你已經創建了'Term'的Set,但是試圖添加一個'Common'的實例。 –

+0

是的,現在我意識到如果我想添加()我需要在終端符號的枚舉中添加EPSILON符號,但是我需要在常用枚舉中使用這個epsilon符號,所以我必須使用'HashSet'解決方案:D –

回答

3

EnumSet從它嚴格包含單個枚舉的成員的關鍵約束中提取效率。它通過依靠每個枚舉成員的ordinal號碼有效地存儲其狀態來實現此目的,其基本行爲類似於BitSet。所以很遺憾,如果你想要多個枚舉,你將無法獲得它的好處。

最接近這個目標的是通過設計自己的編號方案來區分所有枚舉,並使用BitSet來有效地存儲它們。

4

EnumSet只能包含一個枚舉類的成員。

Java API documentation

所有的枚舉set的元素必須來自被指定時,明確地或隱含,創建集合當單個枚舉類型。

如您所知,替代方法是使用Set<TerminalSymbol>

0

EnumSetSet接口的特殊實現,僅適用於enumsEnumSet的一個實例只能使用特定的枚舉,因爲它的實現基於枚舉的ordinal

您爲Term創建了EnumSet,並嘗試添加Common的枚舉成員。這顯然是不可能的。您應該爲Common創建EnumSet,或者如果要存儲兩個枚舉的元素,則使用Set的其他實現,例如, HashSet