2015-11-05 38 views
0

我正在一个java web应用程序和数据库表中我有一个类型数字的列。但该列用于存储多个值。 (即权限如下)Java按位运算符多个权限

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

问题

  1. 如果该列有值3 - >然后我需要挑选什么,视图 权限。
  2. 如果该列有值12 - >那么我需要选择添加, 编辑。

像这样

我undserstood喜欢,我们可以通过位运算符做到这一点。任何代码来实现这将是伟大的。

+1

为什么“没有”是一种价值?为什么不把0作为“没有权限”?此外,您可以使用枚举来依赖序号,但{de,}序列化数据库可能是一个挑战。为什么“全部”也是一个独特的价值? – fge

+0

使用相等运算符的任何问题? 'value == 3' –

+3

我会考虑使用BitSet(http://docs.oracle.com/javase/7/docs/api/java/util/BitSet.html),并简单地调用'get()'来检查是否设置了一个位。 – Nim

回答

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

首先,你的权限设置真的很奇怪; “没有”和“全部”是分开的值是,呃。

那么,你可以使用枚举并依赖序号;这是一种黑客,但它可以工作。示例代码:

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

现在,为什么这样工作的:它是因为Enum值的.ordinal()是它的外观在枚举的索引。在这里,NOTHING有序号0和ALL已有序6.因此,如果你是一个int映射到一组权限,你必须检查,对于任何许可P,在整数p个位设置。而这又意味着i & (1 << p.ordinal()) == 1 << p.ordinal()

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


设计考虑:不保存“一无所有”和“全部”作为可能的值。他们都可以映射到整数:

  • 0表示无权限:
  • 所有值来看,加等全部权限(基本上,因为在这里你总共有5个权限,该值将是(1 < < 5)-1)。
+0

这个逻辑依赖于序数枚举值对于所有永恒是相同的 - 否则算法将会中断。 – specializt

+0

@specializt和这种情况。阅读“EnumSet”的文档。 – fge

+0

@fge在你的代码中出现错误if(value&mask) set.add(p);如果(value&mask == mask),if(value&mask == mask)。我正在使用java 1.6 – user3595995

3

我想你的意思位运算和二进制文字。

在你的情况,你将不得不使用一个位掩码(固定版本,谢谢@保罗博丁顿& @Jaroslaw帕夫拉克):

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

+0

这是正确的路要走,除了OP应该使用0作为无,并'''所有可能的权限作为'MASK_ALL'使用,而不是使用硬编码值。实际上,OP很有标准的做法让OP先做了一些研究。 –

+0

好吧,没有“正确”的方式去...但它是这项工作最快的算法之一 - 为可用性的原因,个人可以选择其他答案 – specializt

+0

@JoshTriiJohnston是的,但'|' – harold