Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 正确使用位集替换基于int的标志。可能吗?_Java_Performance_Bit_Bitset - Fatal编程技术网

Java 正确使用位集替换基于int的标志。可能吗?

Java 正确使用位集替换基于int的标志。可能吗?,java,performance,bit,bitset,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; privat

我从用作标志的数据源获取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;  
使用
位集


那么如何使用
位集
(假设
位集
是正确的选择,因为我不需要对位集进行任何更新,只需检查标志即可)

我认为枚举集比位集更可取,尤其是当您只需要只读访问时

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

或者您可以为此编写一个自定义的hibernate用户类型。这些可能会启发您:

我认为使用位掩码就可以了。或者,创建一个包含4个布尔字段的类。为什么要使用
位集
?为什么要用性能来标记问题?@Sweeper:这意味着每种类型都有X个标志(我没有4个)。Jocke:因为我认为从性能角度看,我的方法应该比其他方法更好,但希望听到更多选项,那么为什么不测量它(我知道很难),或者编译并读取字节码。我喜欢你提供的代码片段。它很干净。我真的不确定性能方面是否更好,尤其是如果我需要依赖于库的话。我的用例是从网络源(即int或long over the wire)获取标志,拥有大量具有
角色的此类对象,并将它们保存在本地数据库缓存中。似乎
EnumSet
增加了额外的开销和额外的依赖性,因为我可以直接检查粘贴在帖子中的标志。你的想法是什么?可能是我遗漏了什么?所以如果我得到这个
enumultils.processBitVector(EmployeeRole.class,rolesalong)
首先会如何生成它?我是说
rolesalong
?它是特定于java的吗?转换过程中会有额外的开销,这是真的。然而,枚举集本身上的方法经过了充分优化,因此.contains()应该与您自己的位掩码一样快。如果性能是一个问题,并且转换开销会对此产生影响,我想我也会像您一样坚持使用位掩码方法。除了性能之外,这种方法是Java特有的吗?我的意思是,从网络源代码来看,如果他们没有
EmployeeRole
的代码库,他们如何让
rolesSlong
通过网络发送它?我猜EnumUtils使用普通的位屏蔽方法,所以rolesSlong不是特定于java的。它是64位的,因此允许设置64个不同的标志。我猜它使用了枚举的序数,所以在这个例子中,雇员是第一位,它是第二位,等等。你必须做一些测试来确定。
//write
long rolesAsLong = EnumUtils.generateBitVector(EmployeeRole.class, employee.getRoles())
//read
employee.setRoles(EnumUtils.processBitVector(EmployeeRole.class, rolesAsLong));