我有一个接口
public interface TerminalSymbol {
// methods ...
}
enum
// 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
更有效。我该如何解决这个问题?
EnumSet只能包含一个enum类的成员。
来自Java API文档:
枚举集合中的所有元素必须来自创建该集合时显式或隐式指定的单一枚举类型。
如您所见,另一种选择是使用Set<TerminalSymbol>
。
EnumSet
的效率来自于它严格包含单个enum成员的键约束。它通过依赖于每个枚举成员的ordinal
号有效地存储其状态来实现这一点,基本上就像BitSet
一样。因此,不幸的是,如果你想要多个枚举,你将无法获得它的好处。
最接近此目标的方法是设计自己的编号方案,该方案在所有枚举中都是不同的,并使用BitSet
来有效地存储它们。
EnumSet
是Set
接口的特殊实现,仅适用于enums
。EnumSet
的一个实例只能使用特定的enum,因为它的实现是基于enum的ordinal
。
您为Term
创建了EnumSet
,并尝试添加Common
的枚举成员。这显然是不可能的。您应该为Common
创建EnumSet
,或者如果您想在那里存储两个枚举的元素,则使用Set
的其他实现,例如HashSet
。