正确使用 BitSet 来替换基于 int 的标志。可能吗?
Using BitSet properly to replace int based flag. Is it possible?
我正在从用作标志的数据源中获取一个整数。示例:
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));
或者您可以为此编写自定义休眠 UserType。这些可能会启发您:https://github.com/search?q=EnumSetUserType&type=Code
我正在从用作标志的数据源中获取一个整数。示例:
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));
或者您可以为此编写自定义休眠 UserType。这些可能会启发您:https://github.com/search?q=EnumSetUserType&type=Code