2015-11-05 205 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