每个枚举项的编号?
是否有可能在java中定义这样的东西?
C#代码:
public enum Character { A = 1, B = 2, C = 4, D = 8 } ... Character ch = /* from user */ if(ch & Character.A) { // some operation... }
例如,如果ch
设置为Character.B
则if
结果将为false
:
ch = 00000000 00000000 00000000 00000010 A = 00000000 00000000 00000000 00000001 ------------------------------------------ & 00000000 00000000 00000000 00000000
我想实现类似的东西! 在Java中它有可能吗?
好吧,你几乎可以这样做:
public enum CharEnum // Let's avoid java.lang.* clashes { A(1), B(2), C(4), D(8); private final int mask; private CharEnum(int mask) { this.mask = mask; } public int getMask() { return mask; } }
然后:
CharEnum ch = /* from user */ if ((ch.getMask() & CharEnum.A.getMask()) > 0) { // some operation... }
这在某些情况下很有用,但正如迈克尔所说,你肯定应该看看EnumSet
的一般“值集”选项。
如果您决定使用值来获取枚举,则可以在枚举本身中添加额外的逻辑:
public enum CharEnum { // Other code as before public boolean overlapsWith(CharEnum ch) { return (ch.mask & mask) > 0; } }
(当然,选择Character
作为枚举的名称非常混乱,因为它会与java.lang.Character
产生冲突,并自动导入每个编译单元)
您可以使用ordinal()方法获取与枚举常量关联的整数。 无论如何,我觉得你想要实现的目标可以通过枚举定义的方法来实现。 我的意思是,Java的枚举比C / C ++更强大,因为你可以将行为与它们联系起来。
public enum Chr { A { @Override public void doSomething(int c) { // some operation ... } }, B, C, D; public void doSomething(int c) { // some default behavior } }
发表评论后:
您可以定义一个保存此值的字段,并让构造函数初始化它,如下所示:
public enum Chr { A(1), B(2), C(4), D(8) ; public Chr(int n) { value = n; } public final int value; } Character ch = ... // from user if(ch & Chr.A.value) { ... }
你可以使用Enum.ordinal()
做类似的事情,但这将是非常糟糕的设计。 您应该使用==
进行相等比较,使用EnumSet
进行集合操作。
我同意Itay,为了进一步了解,我建议阅读Effective Java Second Edition,其中有一章真正有趣的Java枚举。
我同意Michael Borgwardt和Jon Skeet认为EnumSet
值得关注。 我会选择像你一样的按位运算EnumSet
,所以我将演示如何使用EnumSet
。
它看起来像你的 (从现在开始我们称之为Character
enumCharEnum
) CharEnum
被用作比特字段,其中每个枚举都有一个int值,只有一个位集:
A = 00000000 00000000 00000000 00000001 B = 00000000 00000000 00000000 00000010 C = 00000000 00000000 00000000 00000100 D = 00000000 00000000 00000000 00001000
这与EnumSet
为您所做的非常相似; 它有一个内部位向量,可以自动将每个枚举分配给long
。 正如JavaDoc所说, “这个类的空间和时间性能应该足够好,可以作为传统的基于int的”位标志的高质量,类型安全的替代品。“
这是一个如何使用它的例子
public enum CharEnum { A, B, C, D; }
接着
EnumSet ch = /* from user */ if (ch.contains(CharEnum.A)) { // some operation... }
无需在任何地方指定位,因此代码更简单!
警告:这只能起作用,因为C#示例中的枚举值每个只设置一个位。 如果你有这样的枚举值:
E = 00011000 01110111 11100101 10000101
那么EnumSet
就不合适了。 在这种情况下,您应该在这里查看其中一个答案。