java - 正确使用 BitSet 来替换基于 int 的标志。是否可以?

标签 java performance bit bitset

我从数据源获取一个 int 作为标志。示例:

private static final int EMPLOYEE   =     0x00000001;  
private static final int IT         =     0x00000002;  
private static final int MARKETING  =     0x00000004;  
private static final int DATA        =    0x00000008;  
private static final int DBAs = IT | DATA;  
private static final int DATA_REPORTERS = MARKETING | DATA;  

private static boolean isDba(int flag){
  return (flag & DBAs) == flag;
}

private static boolean isInIT(int flag) {
  return (flag & IT) == flag;
}

class Employee {
  private int role;  
  private final String name;    
  //etc 
}  

employee = fetchEmployee()
if(isDba(employee.role)){
   System.out.println("Is a DBA");
}

这似乎工作正常,但我也在研究EnumSet,以防我可以稍微简化代码,但在我看来,它似乎没有做到这一点。
例如我需要:

private static final int EMPLOYEE   =     1;  // bit 1
private static final int IT         =     2;  // bit 2
private static final int MARKETING  =     3;  // bit 3
private static final int DATA        =    4;  // bit 4

哪些是要设置的各个位,但我可以弄清楚如何完成以下操作:

private static final int DBAs = IT | DATA;  
private static final int DATA_REPORTERS = MARKETING | DATA;  

BitSet

那么如何使用 BitSet 正确实现上述内容(假设 BitSet 是正确的选择,因为我不需要对位集进行任何更新)检查标志)

最佳答案

我认为 EnumSet 比 BitSet 更好,特别是如果您只需要只读访问权限。

enum EmployeeRole {
  EMPLOYEE, IT, MARKETING, DATA
}

EnumSet<EmployeeRole> DBAs = EnumSet.of(IT, DATA);
EnumSet<EmployeeRole> DATA_REPORTERS = EnumSet.of(MARKETING, DATA);

class Employee {
  EnumSet<EmployeeRole> roles;

  boolean isDba(){
     for(EmployeeRole role: roles){
       if(DBAs.contains(role){
         return true;
       }
     }
     return false;
  }
}

但是,如果您将标志作为数据库中的单个字段存储在数据库中,则需要进行转换,例如使用旧的 apache commons-lang EnumUtils

//write
long rolesAsLong = EnumUtils.generateBitVector(EmployeeRole.class, employee.getRoles())
//read
employee.setRoles(EnumUtils.processBitVector(EmployeeRole.class, rolesAsLong));

或者您可以为此编写一个自定义的 hibernate 用户类型。这些可能会启发您:https://github.com/search?q=EnumSetUserType&type=Code

关于java - 正确使用 BitSet 来替换基于 int 的标志。是否可以?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60886183/

相关文章:

java - 如何加速 JTable 内置的表格排序?

java - 为什么在将字节数组转换为字符串然后再转换回字节数组时长度不同?

java - 在oracle表中插入带有空字符中间的字符串

Java String.matches 正则表达式

c++ - 如何将 4 个 2 位值合并为 1 个 8 位值?

c++ - 在 TypeScript 中翻译 c++ 函数

sql - 选择具有默认值的可空位

java - 使用 spring-boot 的 Maven 模块

android - 使用 libgdx 绘制大背景图像 - 最佳实践?

c++ - 常量指针 C++ 和优化,它们更快吗?