采用位运算对状态进行表示

前沿

最近在看反射,发现反射中有一个Modifier类,Filed、Consturctor、Method中都有getModifiers()方法,方法返回表示此对象的java语言修饰符,返回值类型为int,这里有个疑问为什么int的数字可以表示java修饰符,因为好奇,点进源码一探究竟。

首先,我们看看Modifier类中定义的静态常量,采用16进制计数

 /**
     * The {@code int} value representing the {@code public}
     * modifier.
     */
    public static final int PUBLIC           = 0x00000001;

    /**
     * The {@code int} value representing the {@code private}
     * modifier.
     */
    public static final int PRIVATE          = 0x00000002;

    /**
     * The {@code int} value representing the {@code protected}
     * modifier.
     */
    public static final int PROTECTED        = 0x00000004;

    /**
     * The {@code int} value representing the {@code static}
     * modifier.
     */
    public static final int STATIC           = 0x00000008;

再看看它的静态方法,采用的是位与运算,如果getModifiers()方法的返回值&public对应的16进制值为非0的话,就说明含有public修饰符

public static boolean isPublic(int mod) {
        return (mod & PUBLIC) != 0;
    }

扩展

如果只是针对两个状态字段的判断,我们就可以采用位运算来表示就很方便了。

比如说用户的状态类,用户是否完成手机认证,是否完成邮箱认证,是否完成基本资料等等,如果单独都写一个字段表示的话,数据库多一个状态就多需要多一列来表示。我们可不可以用一列可以表示完所有的状态呢?答案是肯定可以的,我们可以采用位运算来表示。举例说明:我们新建一个记录状态的类BitStates,创建所需要表示的状态,如下

	/**
	 * 是否手机认证
	 */
	public final static int OP_AUTHED_PHONE = 1 << 3;
	/**
	 * 是否邮箱认证
	 */
	public final static int OP_AUTHED_EMAIL = 1 << 4;
	
	/**
	 * 是否完善个人信息
	 */
	public final static int OP_SAVE_BASIC_INFO = 1 << 5;

简单的说下1 << 3表示的是位运算的左移3位,比如0000 0001左移三位则变成0000 1000,表示的数值就是8,1 << 4左移4位则是0001 0000表示的数值是16,这样一个位就可以用于表示一个状态,也有相对应的值,当然int类型是32位的,这里只是简单描述下。

那么问题来了

  1.   如何表示新增状态
  2.   如何删除状态
  3.   如何查询状态

比如:用户表中的状态值为24,换成二进制位00011000,想知道用户是否完成手机认证,采用 & 运算,规则是同为1则为1,否则都为0

               00011000

         &    00001000 

          =   00001000  

结果:刚好等于是否手机认证的值,说明包含手机认证状态

接着上面的状态值,如果想添加某一状态,比如用户已完成基本资料,采用 | 运算,规则是只有同为0则为0,否则为1

              00011000

        |     00100000 

        =    00111000

  结果:在原来的基础上增加了一个状态

如果删除一个状态,我想删除手机认证,采用 ^ 运算,规则是相同为0,不同为1,我每次记的时候是只有异性才可以生成孩子,同性不行

              00111000

         ^   00001000

         =   00110000

结果:在原来的基础上少了一个状态

代码如下:

/**
	 * @param states 用户当前状态值
	 * @param value  需要判断状态值
	 * @return 是否存在
	 */
	public static boolean hasState(long states,long value){
		return (states & value) == value;
	}
	
	/**
	 * @param states 已有状态值
	 * @param value  需要添加状态值
	 * @return 新的状态值
	 */
	public static long addState(long states,long value){
		if(hasState(states, value)){
			return states;
		}
		return (states | value);
	}
	
	/**
	 * @param states 已有状态值
	 * @param value  需要删除状态值
	 * @return 新的状态值
	 */
	public static long removeState(long states,long value){
		if(!hasState(states, value)){
			return states;
		}
		return states ^ value;
	}

 

上一篇:访问者模式软件架构报告


下一篇:Python实现的贪婪算法