记与运算的一种运用方式

与运算,是位运算的一种。一句话概括它就是:同为1即为1,否则为零。在最近的项目中,学习到了与运算的一种使用方式。即当产品A关联到其他多个产品时,只需在产品A里添加一个字段用来保存一个关联的数值,该数值与其他产品指定的数值进行与运算即可算出产品A是否与该产品关联。说起来有点拗口,看下案例就明白了。

案例分析

如果一个系统提供给多个用户使用的话,一般会规定一些角色,然后把角色分配给指定职能的用户。假设某个系统里的角色有:系统管理(拥有整个系统操作权限的角色)、配置管理(专门负责系统参数配置管理的角色)、值班(只有少部分关于值班功能的操作权限)、数据查看(只有关于数据展示功能块的操作权限)…

一般情况下,系统管理属于内置角色,只有管理人员掌握该权限。普通工作人员掌握着值班和数据查看的操作权限。而系统维护人员掌握配置管理、数据查看的权限。如下表:

人员角色对应表

接下来,看看实现方式。

实现方法

首先,需要创建两个BEAN,一个是关于人员的,包含名字和一个保存关联的字段;一个是关于角色,包含角色名称和角色编号

角色编号对应表

具体操作方法如下:当人员A同时拥有数据查看和值班两个角色时(角色编号分别为2和3),人员A的关联字段保存的数值为12(2^2 + 2^3,即2的编号次方的累加)。

  1. 创建两个bean,一个是关于人员的,包含名字和一个保存管理的字段;一个是关于角色,包含角色名称和角色编号

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    /**
    * 人员Bean
    */
    public class worker {
    int relationId;
    String name;
    public worker(int relationId,String name){
    this.relationId = relationId;
    this.name = name;
    }
    public int getRelationId() {
    return relationId;
    }
    public void setRelationId(int relationId) {
    this.relationId = relationId;
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    }
    /**
    * 角色Bean
    */
    public class Role {
    int id;
    String roleName;
    public Role(int id,String roleName){
    this.id = id;
    this.roleName = roleName;
    }
    public int getId() {
    return id;
    }
    public void setId(int id) {
    this.id = id;
    }
    public String getRoleName() {
    return roleName;
    }
    public void setRoleName(String roleName) {
    this.roleName = roleName;
    }
    }
  2. 为了省(tou)事(lan),需要的数据不进行获取了,这边直接给定

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    List<worker> workerList = new ArrayList<worker>();
    //管理人员的角色是系统管理,编号是1,所以给定的关联id是2;
    workerList.add(new worker(2, "管理人员"));
    workerList.add(new worker(12, "工作人员"));
    workerList.add(new worker(20, "维护人员"));
    List<Role> roleList = new ArrayList<Role>();
    roleList.add(new Role(1, "系统管理"));
    roleList.add(new Role(2, "数据查看"));
    roleList.add(new Role(3, "值班"));
    roleList.add(new Role(4, "配置管理"));
  3. 接下来,来看看分配的权限对不对。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    int workerListSize = workerList.size();
    int roleListSize = roleList.size();
    for (int i = 0; i < workerListSize; i++) {
    System.out.println("");
    System.out.println("人物:"+workerList.get(i).getName());
    System.out.println("拥有的权限为:");
    int role = workerList.get(i).getRelationId();
    for (int j = 0; j < roleListSize; j++) {
    int roleItem = roleList.get(j).getId();
    int rolePow = (int) Math.pow(2, roleItem);
    if((role&rolePow)>0){
    System.out.println(roleList.get(j).getRoleName());
    }
    }
    System.out.println("");
    }
  4. 运行结果为:

    1
    2
    3
    4
    5
    6
    7
    8
    人物:管理人员
    拥有的权限为:系统管理
    人物:工作人员
    拥有的权限为:数据查看,值班
    人物:维护人员
    拥有的权限为:数据查看,配置管理

总结

这种方法,在一个关联多个时,确实也比较好使,尤其是回填时,只需要查询出这个数,然后在代码里进行判断关联就可以了。不过这个方法也有一定的弊端。因为是以2的次方进行累加的,如果关联的个数超过一定个数(比如32个?),累加的数如果还是int类型的话就有溢出的可能,这是需要注意的地方。

编码更多时候并不是写出一劳永逸的代码,而是根据具体需要写出确实可行的代码来。同样的方法也无好坏之分,只要是合适的就可以用。

1
2
3
4
5
6
7
作者:Jarvis
出处:http://huangzihao.me
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,
否则保留追究法律责任的权利。
黄自豪 wechat
欢迎我的公众号!
如果你觉得文章对你有帮助,可点击下面的打赏按钮,支持一下!