Using BitSet properly to replace int based flag. Is it possible?

0

I am getting an int from a data source that serves as a flag. Example:

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

This seems to work ok but I also was looking into the EnumSet in case I can simplify the code a bit bit it does not seem to me that it does.
E.g I would need to have:

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

Which are the individual bits to set but I can figure out how the following can be done:

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

with BitSet

So how would the above be implemented properly with a BitSet (assuming that BitSet is the right choice since I don't need to do any updates on the bitset just check the flags)

java
performance
bit
bitset
asked on Stack Overflow Mar 27, 2020 by Jim

1 Answer

1

I think an EnumSet is preferable to a BitSet, especially if you only need readOnly access.

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

But if you store your flags in a database as a single field in the database, you need a conversion, e.g. using good old apache commons-lang EnumUtils

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

Or you can write a custom hibernate UserType for that. These might inspire you: https://github.com/search?q=EnumSetUserType&type=Code

answered on Stack Overflow Mar 27, 2020 by GreyFairer

User contributions licensed under CC BY-SA 3.0