Java位运算基础及应用

191 阅读2分钟

1. 位运算基础

1、位运算是针对整数的二进制进行的位移操作
2、整数 32位 , 正数符号为0,负数符号为1。十进制转二进制 不足32位的,最高位补符号位,其余补零
3、在Java中,整数的二进制是以补码的形式存在的
4、位运算计算完,还是补码的形式,要转成原码,再得出十进制值
5、正数:原码=反码=补码 负数:反码=原码忽略符号位取反, 补码=反码+1

例如:十进制4 转二进制在计算机中表示为(补码) 00000000 00000000 00000000 00000100

例如:十进制-4 转二进制在计算机中表示为(补码) 11111111 11111111 11111111 11111100

负数转二进制过程(以-4为例)

原码:10000000 00000000 00000000 00000100(转二进制,最高位为符号位)  
反码:11111111 11111111 11111111 11111011(符号位不变,其余取反)  
补码:11111111 11111111 11111111 11111100(反码+1)

-4 << 1 计算过程

-4 补码  11111111 11111111 11111111 11111100  
左移一位 11111111 11111111 11111111 11111000 (这时候还是补码)
# 如果最高位符号位为0,就不需要继续操作了,因为正数的补码=原码,如果最高位是1,继续往下走
转成反码 11111111 11111111 11111111 11110111 (补码-1)  
转成原码 10000000 00000000 00000000 00001000 (忽略符号位取反)  
转十进制 -8 
  • 左移( << ) 整体左移,右边空出位补零,左边位舍弃 (-4 << 1 = -8)
  • 右移( >> ) 整体右移,左边空出位补零或补1(负数补1,整数补0),右边位舍弃 (-4 >> 1 = -2)
  • 无符号右移( >>> )同>>,但不管正数还是负数都左边位都补0 (-4 >>> 1 = 2147483646)
  • 与( & )每一位进行比较,两位都为1,结果为1,否则为0(-4 & 1 = 0)
  • 或( | )每一位进行比较,两位有一位是1,结果就是1(-4 | 1 = -3)
  • 非( ~ ) 每一位进行比较,按位取反(符号位也要取反)(~ -4 = 3)
  • 异或( ^ )每一位进行比较,相同为0,不同为1(^ -4 = -3)

2. 位运算的应用

public class NewPermission {
        // 是否允许查询,二进制第1位,0表示否,1表示是
        public static final int ALLOW_SELECT = 1 << 0; // 0001

        // 是否允许新增,二进制第2位,0表示否,1表示是
	public static final int ALLOW_INSERT = 1 << 1; // 0010

	// 是否允许修改,二进制第3位,0表示否,1表示是
	public static final int ALLOW_UPDATE = 1 << 2; // 0100

	// 是否允许删除,二进制第4位,0表示否,1表示是
	public static final int ALLOW_DELETE = 1 << 3; // 1000

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

	/**
	 *  重新设置权限
	 */
	public void setPermission(int permission) {
		flag = permission;
	}

	/**
	 *  添加一项或多项权限
	 */
	public void enable(int permission) {
		flag |= permission;
	}

	/**
	 *  删除一项或多项权限
	 */
	public void disable(int permission) {
		flag &= ~permission;
	}

	/**
	 *  是否拥某些权限
	 */
	public boolean isAllow(int permission) {
		return (flag & permission) == permission;
	}

	/**
	 *  是否禁用了某些权限
	 */
	public boolean isNotAllow(int permission) {
		return (flag & permission) == 0;
	}

	/**
	 *  是否仅仅拥有某些权限
	 */
	public boolean isOnlyAllow(int permission) {
		return flag == permission;
	}
}

添加Insert、Update、Delete三项权限

permission.enable(NewPermission.ALLOW_INSERT 
    | NewPermission.ALLOW_UPDATE | NewPermission.ALLOW_DELETE);

判断是否允许Select和Insert、Update权限

if (permission. isAllow (NewPermission.ALLOW_SELECT 
    | NewPermission.ALLOW_INSERT | NewPermission.ALLOW_UPDATE)) 

判断是只否允许Select和Insert权限

if (permission. isOnlyAllow (NewPermission.ALLOW_SELECT | NewPermission.ALLOW_INSERT))

也可以优化为Enum方式

public class Text {

    public enum Style {
        BOLD, ITALIC, UNDERLINE, STRIKETHROUGH
    }

    public void applyStyles(Set<Style> styles) {
        System.out.println(styles);
    }
}