每个枚举项的编号?

时间:2010-07-29 07:26:45

标签: java integer enums bit-manipulation

是否可以在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?

5 个答案:

答案 0 :(得分:24)

嗯,你可以几乎这样做:

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;
    }
}

答案 1 :(得分:5)

(当然,选择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) {
     ...
  }

答案 2 :(得分:2)

你可以使用Enum.ordinal()做类似的事情,但设计真的很糟糕。您应该使用==进行相等比较,使用EnumSet进行集合操作。

答案 3 :(得分:2)

我同意Itay,为了进一步了解,我建议您阅读 Effective Java Second Edition ,其中有一整章真正有趣的Java枚举。

答案 4 :(得分:2)

我同意Michael Borgwardt和Jon Skeet的观点,EnumSet值得关注。我会像你一样选择EnumSet按位操作,所以我将演示如何使用EnumSet

看起来你的 Character enum (从现在开始我们称之为CharEnumCharEnum被用作比特字段,其中每个枚举都有只设置一位的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的”位标志“的高质量,类型安全的替代品。” < / p>

以下是如何使用它的示例

public enum CharEnum {
    A, B, C, D;
}

然后

EnumSet<CharEnum> ch = /* from user */

if (ch.contains(CharEnum.A)) {
    // some operation...
}

无需在任何地方指定位,因此代码更简单!

警告:这只能起作用,因为C#示例中的枚举值每个只设置一个位。如果你有这样的枚举值:

E  = 00011000 01110111 11100101 10000101

然后EnumSet不合适。在这种情况下,你应该看看其中一个答案。