Java并发编程---位运算

前言:

在我们浏览JDK源码的时候,我们不难发现它运用了许多的位运算。虽然表面上加大了阅读的难度,但它的运行效率更高,而且减少了许多变量的定义。下面我们就简单地了解一下位运算,并以一个实际例子阐述一下它的实际应用。

位运算:

  1. 位与 &
    1 & 1 =1
    1 & 0 =0
    0 & 0 = 0
  2. 位或 |
    1 | 1 =1
    1 | 0 =1
    0 | 0 =0
  3. 位非 ~
    ~1 = 0
    ~ 0 = 1
  4. 位异或 ^
    1 ^ 1 = 0
    1 ^ 0 =1
    0 ^ 0 = 0
  5. 有符号左移 <<
    有符号右移 >>
    (规则:符号位不变,正数高位补1,负数高位补0)
  6. 无符号右移:>>>
    (规则:高位都补0)
  7. 取模操作:
    a % (2 ^ n ) 等价于 a & (2 ^ n -1)

简单的代码示例:

package 位运算;


public class InToBinary {
    public static void main(String[] args) {

        int data = 4;
        System.out.println("the "+data+" is "+Integer.toBinaryString(data));

        //位与 & (1&1=1 1&0=0 0&0=0)
        System.out.println("the 4 is "+Integer.toBinaryString(4));
        System.out.println("the 6 is "+Integer.toBinaryString(6));
        System.out.println("the 4&6 is "+Integer.toBinaryString(4&6));
        //位或 | (1|1=1 1|0=1 0|0=0)
        System.out.println("the 4|6 is "+Integer.toBinaryString(4|6));
        //位非 ~ (~1=0  ~0=1)
        System.out.println("the ~4 is "+Integer.toBinaryString(~4));
        //位异或 ^ (1^1=0 1^0=1 0^0=0)
        System.out.println("the 4^6 is "+Integer.toBinaryString(4^6));

        //取摸的操作 a % (2^n) 等价于 a & (2^n-1)
        System.out.println("the 345 % 16 is "+(345%16)+
        " or "+(345&(16-1)));
    }
}

结果展示:
在这里插入图片描述

经过上面的例子,我们只能初步了解它的运算规则,可有人就会问了,它在我们实际生活中有什么应用呢?

在实际应用中,用户的权限设置难免少不了对数据的增删查改,可能在还不了解位运算时,我们最常使用的是使用几个标志位进行判断,可当我们权限增多时,我们就得不断地定义标志位,这样会使我们的程序代码变得相当累赘,而如果使用了位运算进行标识的话,我们的标志位会大大缩减,只需用一个int型的二进制位(能表示32种权限)来表示,每位二进制位表示一种权限,这样我们就大大简化了 代码数量,也极大地优化了我们进行权限判断等步骤。(在实际电商的应用中使用二进制位来表示不同商品的属性非常常见)

简单的代码示例:[我们一开始设置它拥有增删改查的所有权限,然后使用删除权限(删除了可删除和可插入的权限), 然后判断修改后我们相关权限是否拥有。]

package 位运算;

/**
 * 权限的设置
 */
public class Permission {

    //是否允许查询,二进制第一位,0表示否,1表示是
    public static final int ALLOW_SELECT = 1 << 0; //0001 = 1
    //是否允许新增,二进制第二位,0表示否,1表示是
    public static final int ALLOW_INSERT = 1 << 1; //0010 = 2
    //是否允许修改,二进制第三位,0表示否,1表示是
    public static final int ALLOW_UPDATE = 1 << 2; //0100 = 4
    //是否允许删除,二进制第四位,0表示否,1表示是
    public static final int ALLOW_DELETE = 1 << 3; //1000 = 8

    //存储目前大的权限状态
    private int flag;

    //设置用户权限
    public void setPer(int per){
        flag = per;
    }
    //增加用户权限(1个或者多个)
    public void enable(int per){
        flag = flag|per;
    }
    //删除用户的权限(1个或者多个)
    public void disable(int per){
        flag = flag&~per;
    }
    //判断用户的权限
    public boolean isAllow(int per){
        return ((flag & per) == per);
    }
    //判断用户没有的权限
    public boolean isNotAllow(int per){
        return ((flag & per) ==0);
    }
   //我们一开始设置它拥有增删改查的所有权限,然后使用删除权限(删除了可删除和可插入的权限)
   //然后判断修改后我们相关权限是否拥有
    public static void main(String[] args) {
        int flag = 15;
        Permission permission = new Permission();
        permission.setPer(flag);
        permission.disable(ALLOW_DELETE|ALLOW_INSERT);
        System.out.println("select = "+permission.isAllow(ALLOW_SELECT));
        System.out.println("insert = "+permission.isAllow(ALLOW_INSERT));
        System.out.println("update = "+permission.isAllow(ALLOW_UPDATE));
        System.out.println("delete = "+permission.isAllow(ALLOW_DELETE));
    }
}

结果展示
在这里插入图片描述
总结:位运算不仅在JDK的源码中到处可见,在我们设计相关用户权限和商品属性也是非常常见的,所以我们只要了解相关的运算规则,再以简单的例子做辅助,在以后的应用设计中,我们就会得心应手了。

发布了19 篇原创文章 · 获赞 2 · 访问量 415

猜你喜欢

转载自blog.csdn.net/TheWindOfSon/article/details/103963755