使用实现接口的枚举的EnumSet

时间:2013-05-16 18:50:34

标签: java enums 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更有效率。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:4)

EnumSet只能包含一个枚举类的成员。

来自Java API documentation

  

枚举集中的所有元素必须来自在创建集时明确或隐式指定的单个枚举类型。

如您所知,另一种方法是使用Set<TerminalSymbol>

答案 1 :(得分:3)

EnumSet从严格包含单个枚举成员的关键约束中提取效率。它通过依赖每个枚举成员的ordinal个数来有效地存储其状态来实现这一点,基本上表现得像BitSet。所以很遗憾,如果你想要多个枚举,你将无法获益。

您可以达到这个目标的最接近的方法是设计自己的编号方案,该方案在所有枚举中都是不同的,并使用BitSet来有效地存储它们。

答案 2 :(得分:0)

EnumSet仅是Set的{​​{1}}接口的特殊实现。 enums的一个实例只能使用特定的枚举,因为它的实现基于枚举的EnumSet

您为ordinal创建了EnumSet,并尝试在其中添加Term的枚举成员。这显然是不可能的。您应该为Common创建EnumSet,或者如果要存储两个枚举的元素,请使用Common的其他实现,例如Set