Java Bitwise&运营商多次许可

时间:2015-11-05 11:59:57

标签: java bitwise-operators

我正在研究java Web应用程序,在数据库表中我有一个类型为number的列。但该列用于存储多个值。 (即如下所示的许可)

  1. 没有= 1;
  2. view = 2;
  3. add = 4;
  4. edit = 8;
  5. insert = 16;
  6. delete = 32;
  7. all = 64;
  8. 问题

    1. 如果该列的值为3 - >然后我需要选择任何东西,视为 许可。
    2. 如果该列的值为12 - >然后我需要选择添加,     编辑。
    3. 类似这样的事情

      我没有理解我们可以通过按位运算符来实现这一点。任何实现这一目标的代码都会很棒。

3 个答案:

答案 0 :(得分:3)

首先,你的权限集非常奇怪; “没有”和“所有”是分开的价值是,呃。

嗯,你可以使用枚举并依靠序数;它有点hackish但它可以工作。示例代码:

public enum Permission
{
    NOTHING,
    VIEW,
    ADD,
    EDIT,
    INSERT,
    DELETE,
    ALL,
    ;

    private static final Set<Permission> ALL_PERMISSIONS;

    static {
        final Set<Permission> set = values();
        set.remove(NOTHING);
        set.remove(ALL);
        ALL_PERMISSIONS = Collections.unmodifiableSet(set);
    }

    private static final int NOTHING_ORDINAL = NOTHING.ordinal();
    private static final int ALL_ORDINAL = ALL.ordinal();

    public static Set<Permission> fromInt(final int value)
    {
        int mask;

        mask = 1 << NOTHING_ORDINAL;
        if (value & mask == mask)
            return Collections.emptySet();

        mask = 1 << ALL_ORDINAL;
        if (value & mask == mask)
            return ALL_PERMISSIONS;

        final Set<Permission> set = EnumSet.noneOf(Permission.class);

        for (final Permission p: ALL_PERMISSIONS) {
            mask = 1 << p.ordinal();
            if (value & mask == mask)
                set.add(p);
        }

        return Collections.unmodifiableSet(set);
    }
}

现在,为什么这样做:这是因为.ordinal()值的Enum是枚举中的外观索引。这里,NOTHING有序号0,ALL有序数6.因此,如果你要将int映射到一组权限,你必须检查任何权限p,p-设置整数位。反过来,这意味着i & (1 << p.ordinal()) == 1 << p.ordinal()

有关更多信息,请参阅Enum的javadoc。

设计注意事项:请勿将“nothing”和“all”存储为可能的值。它们都可以映射到整数:

  • 0表示没有权限:
  • 所有权限的查看,添加等所有值(基本上,由于此处总共有5个权限,因此值为(1 <&lt; 5) - 1)。

答案 1 :(得分:3)

我认为你的意思是按位操作和二进制文字。

在你的情况下,你必须使用位掩码(修复版,谢谢@Paul Boddington&amp; @Jaroslaw Pawlak):

final int MASK_NOTHING = 1;
final int MASK_VIEW = 0b10;
final int MASK_ADD = 0b100;
final int MASK_EDIT = 0b1000;
final int MASK_INSERT = 0b10000;
final int MASK_DELETE = 0b100000;
final int MASK_ALL = 0b1000000;
int column = 0; //YOUR DATA HERE

if((column & MASK_NOTHING) > 0)
{

}

if((column & MASK_VIEW) > 0)
{

}

请注意:所有可能的bitflags都可以独立设置...因此要么阻止一次设置多个,要么处理所有这些情况

二进制文字:https://docs.oracle.com/javase/7/docs/technotes/guides/language/binary-literals.html运算符:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html

答案 2 :(得分:0)

感谢所有回复。我用bitand运算符创建了一个简单的实用程序,它对上面的用例

非常有用

问题:

1)getPermission(3)将不返回任何内容并进行查看。

public static ArrayList<Integer> getPermission(int day) {
    List<Integer> places = Arrays.asList(1, 2, 4, 8, 16, 32, 64);
    ArrayList<Integer> d = new ArrayList<Integer>();
    for (Integer i : places) {
        if (bitWiseAnd(day, i)) {
            d.add(i);
        }
    }
    return d;
}

public static boolean bitWiseAnd(int bitwise, int operator) {
    return (bitwise & operator) > 0;
}