二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是逢二进一,借位规则是借一当二。因为它只使用0、1两个数字符号,非常简单方便。

常用位运算
- 位与 & (1&1=1 0&0=0 1&0=0)
- 位或 | (1|1=1 0|0=0 1|0=1)
- 位非 (1=0 ~0=1)
- 位异或 ^ (1^1=0 1^0=1 0^0=0)
- 有符号右移>>(若正数,高位补0,负数,高位补1)
- 有符号左移<<
- 无符号右移>>>(不论正负,高位均补0)
有趣的取模性质:取模 a % (2^n) 等价于 a & (2^n - 1),所以在 map 里的数组个数一定是 2 的乘方数,计算 key 值在哪个元素中的时候,就用位运算来快速定位。
位运算结果
/**
* 位运算
*/
public class IntToBinary {
public static void main(String[] args) {
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(6 & 4));
//位或|(真真为真 真假为真 假假为假)
System.out.println("the 4|6 is : " + Integer.toBinaryString(6 | 4));
//位非~
System.out.println("the ~4 is : " + Integer.toBinaryString(~4));
//位异或^(真真为假 真假为真 假假为假)
System.out.println("the 4^6 is : " + Integer.toBinaryString(6 ^ 4));
//有符号右移>>(若正数,高位补0,负数,高位补1)
System.out.println("the 4>>1 is : " + Integer.toBinaryString(4 >> 1));
//有符号左移<<(若正数,高位补0,负数,高位补1)
System.out.println("the 4<<1 is : " + Integer.toBinaryString(4 << 1));
//无符号右移>>>(不论正负,高位均补0)
System.out.println("the 234567 is : " + Integer.toBinaryString(234567));
System.out.println("the 234567>>>4 is : " + Integer.toBinaryString(234567 >>> 4));
//无符号右移>>>(不论正负,高位均补0)
System.out.println("the -4 is : " + Integer.toBinaryString(-4));
System.out.println("the -4>>>4 is : " + Integer.toBinaryString(-4 >>> 4));
System.out.println(Integer.parseInt(Integer.toBinaryString(-4 >>> 4), 2));
//取模a % (2^n) 等价于 a & (2^n - 1)
System.out.println("the 345 % 16 is : " + (345 % 16) + " or " + (345 & (16 - 1)));
System.out.println("Mark hashCode is : " + "Mark".hashCode() + "="
+ Integer.toBinaryString("Mark".hashCode()));
System.out.println("Bill hashCode is : " + "Bill".hashCode() + "="
+ Integer.toBinaryString("Bill".hashCode()));
}
}
打印结果:
the 4 is : 100
the 6 is : 110
the 4&6 is : 100
the 4|6 is : 110
the ~4 is : 11111111111111111111111111111011
the 4^6 is : 10
the 4>>1 is : 10
the 4<<1 is : 1000
the 234567 is : 111001010001000111
the 234567>>>4 is : 11100101000100
the -4 is : 11111111111111111111111111111100
the -4>>>4 is : 1111111111111111111111111111
268435455
the 345 % 16 is : 9 or 9
Mark hashCode is : 2390765=1001000111101011101101
Bill hashCode is : 2070567=111111001100000100111
位运算运用场景
- Java中的类修饰符、成员变量修饰符、方法修饰符
- Java容器中的 HashMap 和 ConcurrentHashMap 的实现
- 权限控制或者商品属性
- 简单可逆加密(1^1=0 ; 0^1=1 )
实战:权限控制
/**
* 位运算的运用-权限控制,add,query,modify,del
*/
public class Permission {
private static final int ALLOW_SELECT = 1 << 0;
private static final int ALLOW_INSERT = 1 << 1;
private static final int ALLOW_UPDATE = 1 << 2;
private static final int ALLOW_DELETE = 1 << 3;
//当前的权限状态
private int flag;
public void setPermission(int permission) {
flag = permission;
}
/*增加权限,可以一项或者多项*/
public void addPermission(int permission) {
flag = flag | permission;
}
/*删除权限,可以一项或者多项*/
public void disablePermission(int permission) {
flag = flag & ~permission;
}
/*是否拥有某些权限*/
public boolean isAllow(int permission) {
return (flag & permission) == permission;
}
/*是否不拥有某些权限*/
public boolean isNotAllow(int permission) {
return (flag & permission) == 0;
}
public static void main(String[] args) {
int flag = 15;
Permission permission = new Permission();
permission.setPermission(flag);
permission.disablePermission(ALLOW_DELETE | ALLOW_INSERT);
System.out.println("ALLOW_SELECT=" + permission.isAllow(ALLOW_SELECT));
System.out.println("ALLOW_INSERT=" + permission.isAllow(ALLOW_INSERT));
System.out.println("ALLOW_UPDATE=" + permission.isAllow(ALLOW_UPDATE));
System.out.println("ALLOW_DELETE=" + permission.isAllow(ALLOW_DELETE));
}
}
打印结果:
ALLOW_SELECT=true
ALLOW_INSERT=false
ALLOW_UPDATE=true
ALLOW_DELETE=false
使用位运算的优劣势:
节省很多代码量、效率高、属性变动影响小、不直观。
网友评论