Java 每个枚举项的编号?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3360283/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 22:35:11  来源:igfitidea点击:

Number for each enum item?

javaintegerenumsbit-manipulation

提问by Jalal

Is it possible to define something like this in java?

是否可以在java中定义这样的东西?

C# code:

C#代码:

public enum Character
{
    A = 1,

    B = 2,

    C = 4,

    D = 8

}


...

Character ch = /* from user */

if(ch & Character.A)
{
    // some operation...
}

for example if chset to Character.Bthen result of ifwill be false:

例如,如果ch设置为Character.B那么结果if将是false

ch = 00000000 00000000 00000000 00000010
A  = 00000000 00000000 00000000 00000001
------------------------------------------
&    00000000 00000000 00000000 00000000

I want to implement something like that! Is it ever possible in Java?

我想实现这样的东西!在 Java 中有可能吗?

采纳答案by Jon Skeet

Well, you can nearlydo that:

好吧,你几乎可以做到:

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

Then:

然后:

CharEnum ch = /* from user */

if ((ch.getMask() & CharEnum.A.getMask()) > 0)
{
    // some operation...
}

This can be useful in some situations, but as Michael said you should definitely look at EnumSetfor general "set of values" options.

这在某些情况下很有用,但正如迈克尔所说,您绝对应该查看EnumSet一般的“值集”选项。

If you dodecide to go for an enum with values, you can put extra logic within the enum itself:

如果您确实决定使用带有值的枚举,则可以在枚举本身中添加额外的逻辑:

public enum CharEnum
{
    // Other code as before

    public boolean overlapsWith(CharEnum ch)
    {
        return (ch.mask & mask) > 0;
    }
}

回答by Itay Maman

(Of course, choosing Characteras the name of your enum is very confusing as it creates a conflict with java.lang.Characterwhich is automatically imported into every compilation unit)

(当然,选择Character作为枚举的名称非常令人困惑,因为它会与java.lang.Character自动导入到每个编译单元中的冲突产生冲突)

You can use the ordinal() method to get the integer associated with an enum constant. Anyway, I got a feeling that what you are trying to achieve may be realized by enum-defined methods. I mean, Java's enum are more powerful than C/C++'s because you can associate behavior with them.

您可以使用 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
    }
  }

Following your comment:

按照您的评论:

You can define a field which will hold this value, and have the constructor initialize it, as follows:

您可以定义一个将保存该值的字段,并让构造函数对其进行初始化,如下所示:

  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) {
     ...
  }

回答by Michael Borgwardt

You could do something like that using Enum.ordinal(), but it would be really bad design. You should use ==for equality comparisons and EnumSetfor set operations.

您可以使用 做类似的事情Enum.ordinal(),但这将是非常糟糕的设计。您应该==用于相等比较和EnumSet集合操作。

回答by Manuel Selva

I agree with Itay, and to get a bit further I'll recommend the reading of Effective Java Second Editionhaving a full chapter really interesting on Java enums.

我同意 Itay 的观点,为了进一步了解,我会推荐阅读Effective Java Second Edition,其中有一整章关于 Java 枚举非常有趣。

回答by gutch

I agree with Michael Borgwardt and Jon Skeet that an EnumSetis worth looking at. I would have picked EnumSetover bitwise operations like you've got, so I will demonstrate how to use EnumSet.

我同意 Michael Borgwardt 和 Jon Skeet 的观点,EnumSet值得一看。我会EnumSet像您一样选择按位运算,因此我将演示如何使用EnumSet.

 

 

It looks like your Characterenum(let's call it CharEnumfrom now on) CharEnumis being used like a bit field, where each enum has an int value with just one bit set:

看起来您的Character枚举(让我们CharEnum从现在起称之为)CharEnum就像一个位字段一样被使用,其中每个枚举都有一个 int 值,并且只设置了一位:

A  = 00000000 00000000 00000000 00000001
B  = 00000000 00000000 00000000 00000010
C  = 00000000 00000000 00000000 00000100
D  = 00000000 00000000 00000000 00001000

This is very similar to what an EnumSetdoes for you; it has an internal bit vector that automatically assigns each enum to a bit on a long. As the JavaDoc for it says, "The space and time performance of this class should be good enough to allow its use as a high-quality, typesafe alternative to traditional int-based "bit flags."

这与 anEnumSet为您所做的非常相似;它有一个内部位向量,可以自动将每个枚举分配给long. 正如它的 JavaDoc 所说,“这个类的空间和时间性能应该足够好,可以将其用作传统的基于 int 的“位标志”的高质量、类型安全的替代品。

Here's an example of how to use it

这是一个如何使用它的例子

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

and then

进而

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

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

No need to specify bits anywhere, so it's much simpler code!

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

A warning:this only works because the enum values in your C# example have only one bit set each. If you had an enum value like this:

警告:这只有效,因为您的 C# 示例中的枚举值每个都只设置了一位。如果您有这样的枚举值:

E  = 00011000 01110111 11100101 10000101

then an EnumSetwould not be appropriate. In that case you should look at one of the other answers here.

那么 aEnumSet将不合适。在这种情况下,您应该在这里查看其他答案之一。