位运算 flag mask

http://topic.youkuaiyun.com/u/20120616/15/6c128ac9-7bf3-43ee-83c7-1a8629c54960.html


java源码中充斥着各种flag mask, 那到底什么时候用flag

个人感觉flag mask是使用来替代boolean变量用的,避免更多的变量,也方便调用。


比如:同时拥有多种属性的时候:  
类似于这种:Graphics.HCENTER | Graphics.VCENTER

另外:
public void setFlag(int flag) {
            mFlag |= flag;
}

public boolean isFlag(int flag) {
    return (mFlag & flag) != 0;
}

我这样写的话,其实可以不需要mask,mask到底有什么用呢?

一般mask的使用都是:
public boolean isEnabled() {
    return (mViewFlags & ENABLED_MASK) == ENABLED;

}

public boolean isEnabled() {

    return (mViewFlags & ENABLED) != 0;

}

上面2个有什么区别?

【总结】

from 大飞的指点

上面2个仅当ENABLED只有一个1的时候才相等

if((mInputType&(EditorInfo.TYPE_MASK_CLASS | EditorInfo.TYPE_MASK_VARIATION))

== (EditorInfo.TYPE_CLASS_TEXT  |EditorInfo.TYPE_TEXT_VARIATION_PASSWORD)) {

// 第一种能做这样的判定,同时判断多个条件

}


ps:

可以看看位运算的实际用途:
http://blog.youkuaiyun.com/HainuCrazy/article/details/2802490

位运算

& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0
| 按位或 两个相应的二进制位中只要有一个为1,该位的结果值为1
^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1
~ 取反 ~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0
<< 左移 用来将一个数的各二进制位全部左移N位,右补0
>> 右移 将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0


位掩码:只注意一段数据的某一位或几位,过滤或屏蔽其他不需要的。

### Java位运算练习题及相关解析 #### 一、基础知识回顾 Java中的位运算是基于二进制数的操作,主要包括按位与(&)、按位或(|)、按位异或(^)、按位取反(~),以及左移(<<)和右移(>>)操作。这些运算符可以直接作用于整型变量的每一位[^3]。 以下是常见的位运算符及其功能: - **& (按位与)**:两个相应位都为1时结果才为1。 - **| (按位或)**:只要有一个相应的位为1,则结果就为1。 - **^ (按位异或)**:当两位不同时结果为1;相同时结果为0。 - **~ (按位取反)**:将所有的0变为1,所有的1变为0。 - **<< (左移)**:向左移动指定的位数,在低位补零。 - **>> (带符号右移)**:向右移动指定的位数,高位由原数值的符号位填充。 - **>>> (无符号右移)**:无论正负数,高位均用0填充。 --- #### 二、典型练习题及解析 ##### 1. 判断奇偶性 编写一个程序,利用位运算判断给定的一个整数是否为奇数。 ```java public class OddEvenCheck { public static boolean isOdd(int num) { return (num & 1) != 0; } public static void main(String[] args) { int number = 7; System.out.println(isOdd(number)); // 输出 true } } ``` **解析**: 通过`num & 1`可以提取最低有效位(LSB)。如果LSB为1,则该数为奇数;否则为偶数。 --- ##### 2. 计算二进制中1的数量 写一段代码计算某个整数的二进制表示中有多少个1。 ```java public class CountBits { public static int countOnes(int n) { int count = 0; while (n != 0) { count += (n & 1); n >>= 1; // 右移一位 } return count; } public static void main(String[] args) { int number = 9; // 二进制形式为 1001 System.out.println(countOnes(number)); // 输出 2 } } ``` **解析**: 每次取出最右侧的一位并累加到计数器中,随后将整个数字右移一位直到其值为0为止。 --- ##### 3. 实现交换两数而不借助额外空间 尝试仅使用位运算完成两个整数之间的互换。 ```java public class SwapNumbers { public static void swapWithoutTemp(int a, int b) { System.out.println("Before swapping: a=" + a + ", b=" + b); a ^= b; // 步骤1 b ^= a; // 步骤2 a ^= b; // 步骤3 System.out.println("After swapping: a=" + a + ", b=" + b); } public static void main(String[] args) { swapWithoutTemp(5, 8); // Before: a=5,b=8 After: a=8,b=5 } } ``` **解析**: 此方法依赖XOR特性来达到无需临时存储即可交换的目的。具体原理如下: 假设初始状态a=x,y=b=y; 执行三次XOR之后得到最终的结果即完成了两者位置上的调换过程。 --- ##### 4. 左移实现乘法 创建函数验证能否通过简单的左移代替特定倍率下的乘积运算。 ```java public class MultiplyByShifts { public static int multiplyByPowerOfTwo(int value, int power) { return value << power; } public static void main(String[] args) { int result = multiplyByPowerOfTwo(3, 2); // 等价于 3 * 2² = 12 System.out.println(result); // 输出 12 } } ``` **解析**: 对于任何非负整数k来说,把某数x左移k位相当于将其乘以2ᵏ次方。 --- ##### 5. 使用掩码设置/清除特定位 定义一组宏用于快速修改目标字节串内的某些固定范围标志位的状态。 ```java // 假设我们想控制第N位开关 final int MASK_SET_BIT_NTH = 1 << N; // 设置第N位 final int MASK_CLEAR_BIT_NTH = ~(1 << N); // 清除第N位 int applyMask(int originalValue, boolean setFlag) { if(setFlag){ return originalValue | MASK_SET_BIT_NTH ; }else{ return originalValue & MASK_CLEAR_BIT_NTH ; } } System.out.println(Integer.toBinaryString(applyMask(0b1111_0000 ,true))); // 结果应显示新增激活标记后的模式 System.out.println(Integer.toBinaryString(applyMask(0b1111_0000 ,false))); // 对照组则呈现未改变前原始样式 ``` **解析**: 这里展示了如何构建合适的mask并通过逻辑组合调整单一比特域的行为方式。 --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值