3

我有一个界面

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. 我怎么解决这个问题?

4

3 回答 3

4

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

来自Java API 文档

枚举集合中的所有元素都必须来自一个枚举类型,该枚举类型在创建集合时显式或隐式指定。

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

于 2013-05-16T18:54:21.767 回答
3

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

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

于 2013-05-16T18:58:17.047 回答
0

EnumSetSet只是接口的特殊实现enums。一个实例EnumSet只能使用特定的枚举,因为它的实现是基于ordinal枚举的。

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

于 2013-05-16T18:56:46.670 回答