Java 位运算系列之通过位运算操作状态
文章目录
- 回顾
- 应用
- 总结
回顾
首先来回顾一下位运算,什么是位运算呢?
位运算就是直接对整数在内存中的二进制位进行操作。
在 Java 语言中,位运算有如下这些:
- 左移(<<)。
- 右移(>>)。
- 无符号右移(>>>)。
- 与(&)。
- 或(|)。
- 非(~)。
- 异或(^)。
在本篇文章中,我们所需要用到的有如下几个(其他的后续文章再讲):
- &(与运算):只有当两方都为 true 时,结果才是 true,否则为 false。
- |(或运算):只要当一方为 true 时,结果就是 true,否则为 false。
- ^(异或运算):只要两方不同,结果就是 true,否则为 false。
以 true、false 为例:
true & true = true
true & false = falsetrue | false = true;
false | false = false;true ^ true = false;
true ^ false = true;
以数字运算为例:
6 & 4 = ?
6 | 4 = ?
6 ^ 4 = ?
当以数字运算时,我们首先需要知道这些数字的二进制,假设 6 是 int 类型,那么其二进制如下:
00000000 00000000 00000000 00000110
在 Java 中,int 占了 4 个字节(Byte),一个字节呢又等于 8 个 Bit 位。所以 int 类型的二进制表现形式如上。
在这里为方便讲解,直接取后 8 位:00000110。
4 的二进制码如下:
00000100
在二进制码中,1 为 true,0 为 false,根据这个,我们再来看看 6 & 4
的运算过程:
0000011000000100-----------00000100
对每位的数进行运算后,结果为 4。
再来看看 | 运算:
6 | 4 = ?
6 和 4 的二进制上面已经说了:
0000011000000100-----------00000110
可以发现最后的结果是 6。
最后再来看看 ^ 运算:
6 ^ 4 = ?
0000011000000100-----------00000010
结果是 2。
应用
通过上面的例子,我们已经回顾了 & 、 | 以及 ^ 运算。现在来将它应用到实际的应用中。
假如我们现在要定义一个人的模型,这个人可能会包含有多种性格,比如说什么乐观型、内向型啦…
要是想要知道他包含了哪种性格,那么我们该如何判断呢?
可能在第一时间会想到:
if(这个人是乐观性){....
}else if(这个人是好色型){...
}
那么如果有很多种性格呢?一堆判断写起来真的是很要命…
下面就来介绍一种更简单的方式。首先来定义一组数:
public static final int STATUS_NORMAL = 0;
public static final int STATUS_OPTIMISTIC = 1;
public static final int STATUS_OPEN = 2;
public static final int STATUS_CLOSE = 4;
把它们转换为二进制:
0000 0000 0000 0000
0000 0000 0000 0001
0000 0000 0000 0010
0000 0000 0000 0100
发现其中二进制的规律没有?都是 2 的次幂,并且二进制都只有一个为 1 位,其他都是 0 !
然后再来定义一个变量,用于存储状态(默认值是 0):
private static int mStatus = STATUS_NORMAL;
当我们要保存状态时,直接用 | 运算即可:
mStatus |= STATUS_OPTIMISTIC;
保存的运算过程如下:
00000000执行 | 运算(只要有 1 则为 1)00000001-----------00000001 = 1
相当于就把这个 1 存储到 0 的二进制当中了。
那么如果要判断 mStatus
中是否有某个状态呢?使用 & 运算:
System.out.println((mStatus & STATUS_OPTIMISTIC) != 0);// true,代表有它
计算过程如下:
00000001执行 & 运算(都为 1 才为 1)00000001-----------00000001 = 1
再来判断一个不存在的状态 mStatus & STATUS_OPEN
:
System.out.println((mStatus & STATUS_OPEN) != 0);// false,代表没有它
计算过程如下:
0000000100000010-----------00000000 = 0
可以发现,因为 STATUS_OPEN
这个状态的二进制位,1 的位置处,mStatus
的二进制并没有对于的 1,而又因为其他位都是 0,导致全部归 0,计算出来的结果自然也就是 0 了。
这也就是为什么定义状态的数字中,是 1、2、4 这几位数了,因为他们的特定就是二进制只有一个为 1 的位,其他位都是 0,并同其他数位 1 的位不冲突。
如果换成其他的数,就会有问题了。比如说 3:
mStatus |= 3
计算过程:
0000000000000011-----------00000011 = 3
运算完毕,这时候 mStatus
中已经存储了 3 这个值了,我们再来判断下是否存在 2:
System.out.println((mStatus & 2) != 0);// true,代表有它,但是其实是没有的
0000001100000010-----------00000010 = 2
结果是 true,但是其实我们只存储了 3 到 mStatus
中,结果肯定是错误的。
所以我们在定义的时候,一定不要手滑定义错了数字。
存储和判断已经说了,那么如何取出呢?这时候就要用到 ^ 运算了。
假如现在 mStatus
中已经存储了 STATUS_OPTIMISTIC
状态了,要把它给取出来,这样写即可:
mStatus ^= STATUS_OPTIMISTIC
其中的运算过程:
00000001执行 ^ 运算,两边不相同,则为 true00000001-----------00000000
可以看到状态又回到了最初没有存储 STATUS_OPTIMISTIC
状态的时候了。
最后再来看一个取出的例子,这次是先存储两个状态,然后再取出其中一个:
mStatus |= STATUS_OPTIMISTIC
mStatus |= STATUS_OPEN
存储完后,mStatus
的二进制为:
00000011
再来取出 STATUS_OPEN
这个状态:
mStatus ^= STATUS_OPEN
运算过程:
00000011
00000010
-----------
00000001
mStatus
现在就只有 STATUS_OPTIMISTIC
的状态了。
总结
通过 |、^、& 运算,我们可以很方便快捷的对状态值进行操作。当然,位运算的应用不仅限于状态值,知道了其中的二进制运算原理后,还有更多的其他应用场景,等着你去发现。
Java 位运算系列之通过位运算操作状态相关推荐
- 蓝桥杯算法竞赛系列第一章——位运算的奇巧淫技及其实战
遇见蓝桥遇见你,不负代码不负卿! 第二章"递归"已将更新咯,欢迎铁汁们点评!蓝桥杯算法竞赛系列第二章--深入理解重难点之递归(上)_安然无虞的博客-CSDN博客 目录 一.位运算符 ...
- java加减乘除运算代码_从“位运算”炫技到“操作符”,再到逐步理解“群论”...
由位运算到操作符,再到逐步理解群论 Step by Step for Understanding from Bitwise to Operators, then Group Theory 是否曾经会有 ...
- java反码算术运算求和,位运算的妙用,运算妙用
位运算的妙用,运算妙用 最近在学java,其实仅仅是在命令行里写程序跟C语言没有太大的区别,思想都是一样的.遇到了一个比较新鲜(后来知道原来C中也有)的东西--位元算(又叫位操作).多新鲜啊,毕向东老 ...
- java实现次方的运算_Java中对于位运算的优化以及运用与思考
引言 随着JDK的发展以及JIT的不断优化,我们很多时候都可以写读起来易读但是看上去性能不高的代码了,编译器会帮我们优化代码.之前大学里面学单片机的时候,由于内存以及处理器性能都极其有限(可能很多时候 ...
- java取余位运算_Java中对于位运算的优化以及运用与思考
引言 随着JDK的发展以及JIT的不断优化,我们很多时候都可以写读起来易读但是看上去性能不高的代码了,编译器会帮我们优化代码.之前大学里面学单片机的时候,由于内存以及处理器性能都极其有限(可能很多时候 ...
- Java位运算,常见的位运算
前提 位运算符中 ,操作数只能为整型和字符型数据 运算符号 按位与(&):同1则1 → true&&true 操作数1 0 0 1 1 操作数2 0 1 0 1 按位与 0 0 ...
- 7、Java四种进制及位运算介绍
7.Java四种进制及位运算介绍 四种进制: 二进制:0,1 以0b或0B开头 十进制:0-9 八进制:0-7 以数字0开头 十六进制:0-9 及A(10)-F(15) ,以0x或0X开头,此处A-F ...
- 力扣解题思路:位运算系列
交换两个整数 思路:给定a,b用位运算交换两个数的值: a = a ^ b; b = a ^ b;//b = a ^ b ^ b (这里a,b是初始a,b) a = a ^ b;//a = a ^ b ...
- JAVA PHP 按位异或运算_对php位运算^(按位异或)的理解
最近在看一些加密函数,其中总涉及到一些位运算,尤其是^(按位异或),经过多方查找资料,对^的理解深入,分享资料留作纪念! /* 手册资料: 位运算符 位运算符允许对整型数中指定的位进行置位.如果左右参 ...
最新文章
- javase 超市库存系统
- 成功解决OpenCV Error: Assertion failed (ssize.width 0 ssize.height 0) in cv::resize, file C:\proj
- php随机数字不重复使等式成立_当随机数遇上量子
- transaction type popup window when create service order
- MVC下实现LayUI分页的Demo
- [Array]Majority Element
- python获取服务器文件svn版本信息_如何编程获取SVN版本号?
- 坐标偏差大_三坐标常见撞针原因,总结的太到位了!
- .net core下简单构建高可用服务集群
- VC++中按钮,文本框,选择框的常用方法
- 2014年读过的那些书
- 感悟Microsoft summer Camp 2010
- (附源码)计算机毕业设计ssm 航空订票系统
- IOS 面试个人简历(模板)
- 纬地道路纵断面设计教程_道路BIM模型快速生成
- 计算机 64虚拟内存设置方法,计算机虚拟内存怎样设置
- 大胖子走迷宫 [蓝桥杯 ]
- ANO Tech 匿名四轴 制作分享
- 证券基金经营机构信息技术管理办法
- java word模版填充_Java 数据填充到word模板中