Java - 移位 int 枚举

5
在C语言中,我有时会使用结构体,例如:
enum {
   UIViewAutoresizingNone                 = 0,
   UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
   UIViewAutoresizingFlexibleWidth        = 1 << 1,
   UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
   UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
   UIViewAutoresizingFlexibleHeight       = 1 << 4,
   UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
typedef NSUInteger UIViewAutoresizing;

有没有 Java 的等价物?

为什么?这只是为了处理它们的集合吗? - OrangeDog
8个回答

15

使用EnumSet

上面链接中的摘录作为示例:

package resolver;

import java.util.EnumSet;

public class EnumPatternExample {

    public enum Style {
        BOLD, ITALIC, UNDERLINE, STRIKETHROUGH
    }

    public static void main(String[] args) {
        final EnumSet<Style> styles = EnumSet.noneOf(Style.class);
        styles.addAll(EnumSet.range(Style.BOLD, Style.STRIKETHROUGH)); // enable all constants
        styles.removeAll(EnumSet.of(Style.UNDERLINE, Style.STRIKETHROUGH)); // disable a couple
        assert EnumSet.of(Style.BOLD, Style.ITALIC).equals(styles); // check set contents are correct
        System.out.println(styles);
    }

}

5
您不再需要在Java中使用枚举和二进制逻辑。您只需要使用enum本身和EnumSet即可。
例如:
enum Color {
   Red, Green, Blue, Orange, White, Black
}

...

EnumSet<Color> mainColors = EnumSet.of(Color.Red, Color.Green, Color.Blue);
Color color = getSomeColor();
if (mainColors.contains(color)) {
   //mainColors is like Red | Green | Blue, 
   //and contains() is like color & mainColors
   System.out.println("Your color is either red or blue or green"); 
}

3

我不确定那段C代码具体做什么,但以下是Java中最接近的实现:

enum UIView {
    UIViewAutoresizingNone                 ( 0),
    UIViewAutoresizingFlexibleLeftMargin   ( 1 << 0),
    UIViewAutoresizingFlexibleWidth        ( 1 << 1),
    UIViewAutoresizingFlexibleRightMargin  ( 1 << 2),
    UIViewAutoresizingFlexibleTopMargin    ( 1 << 3),
    UIViewAutoresizingFlexibleHeight       ( 1 << 4),
    UIViewAutoresizingFlexibleBottomMargin ( 1 << 5);
    private final int value;

    private UIView(int value){
        this.value = value;}

    public int getValue(){
        return value;
    }
 };

2
你说得没错,这是同一个程序最接近的Java版本,但从思想上来说是错误的。所有这些移位都是为了使用二进制逻辑与值(1、2、4、8等)即运算符“|”和“&”。Java引入了“EnumSet”,使事情变得更容易,并允许摆脱二进制逻辑。 - Roman
1
@Roman 我完全同意。正如我所说,我甚至不太理解这个位移操作,它是古老时代的遗物。Java将这些细节隐藏起来,我很感激。尽管如此,我的目标是尽可能少地修改代码使其编译通过,我想我已经做到了(即使这没有多少意义)。 - Sean Patrick Floyd

0
你可以像下面这样做:

你可以像下面这样做:

enum EnumTest {
    ONE(1), //Specify value to pass to constructor
    TWO(2),
    THREE(3);

    private int num;

    private EnumTest(int num) { //Enum constructor must be private
        this.num = num;
    }

    public int getNum() { //Get the value specified on the constant's creation
        return num;
    }
}

你可以在枚举上调用getNum()方法,以获取在常量创建时指定的数字。在Java中,枚举比其他语言更强大和灵活 - 它们是后来添加的,但本质上是完整的类(您可以像操作类一样操作它们)。

0

如果不考虑你的不断变化的需求,你可以这样做:

enum MyEnum {
       UIViewAutoresizingNone(0),
       UIViewAutoresizingFlexibleLeftMargin(1),
       UIViewAutoresizingFlexibleWidth(2),
       UIViewAutoresizingFlexibleRightMargin(3),
       UIViewAutoresizingFlexibleTopMargin(4),
       UIViewAutoresizingFlexibleHeight(5),
       UIViewAutoresizingFlexibleBottomMargin(6);

       private int value;

       private MyEnum(int value) {
           this.value = value;
       }

       public int getValue() {
           return value;
       }
    };

0
如果你在谷歌上搜索“Java Enums”,你可以找到如何实现它们的示例。基本上,在Java中,枚举类型就像类一样,它们有构造函数、方法等等...而且你可以将值映射到常量标签,这样你的枚举类型就可以轻松地转换为Java枚举类型。
public enum UIViewAutoresizingConstants
{
    UIViewAutoresizingNone(0),
    UIViewAutoresizingFlexibleLeftMargin(1 << 0);

    private int value;

    private UIViewAutoresizingConstants(int v)
    {
        this.value = v;
    }
}

0

有点类似。您可以定义一个Java枚举并使用您的值构造每个枚举类型:

public enum UIViewAutoresizing {
    None(0),
    FlexibleLeftMargin(1 << 0),
    FlexibleWidth(1 << 1),
    FlexibleRightMargin(1 << 2),
    FlexibleTopMargin(1 << 3),
    FlexibleHeight(1 << 4),
    FlexibleBottomMargin(1 << 5);

    private final int flag;

    private MessageType(int flag) {
        this.flag = flag;
    }

    public int flag() {
        return flag;
    }
};

然后方法flag()将返回您实际的标志值。或者更好的是,您可以在枚举上定义方法,根据标志的值执行一些有用的操作。


0
在Java中,枚举项不能像那样被赋值,你需要类似这样的东西:
public enum Classname {
   UIViewAutoresizingNone( 0 ),
   UIViewAutoresizingFlexibleLeftMargin ( 1 << 0 ),
   UIViewAutoresizingFlexibleWidth( 1 << 1 ),
   UIViewAutoresizingFlexibleRightMargin( 1 << 2 ),
   UIViewAutoresizingFlexibleTopMargin( 1 << 3 ),
   UIViewAutoresizingFlexibleHeight( 1 << 4),
   UIViewAutoresizingFlexibleBottomMargin( 1 << 5 ),

    private final double value;

    // constructor
    private Classname( double v ) {
        this.value = v;
    }

    public double value()   { 
        return value; 
    }
 }

然后在您的其他代码中,您将会得到这样一个值:

double x = Classname.UIViewAutoresizingNone.value;

假设您需要能够从其他代码访问该值,并且您不仅仅是添加它以确保每个枚举值都不同。对于后一种情况,在Java中根本不需要这样做。例如,以下内容将起作用:

public enum Classname {
   UIViewAutoresizingNone,
   UIViewAutoresizingFlexibleLeftMargin,
   UIViewAutoresizingFlexibleWidth,
   ....

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接