300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Java 位运算系列之通过位运算操作状态

Java 位运算系列之通过位运算操作状态

时间:2018-08-05 03:14:49

相关推荐

Java 位运算系列之通过位运算操作状态

文章目录

回顾应用总结

回顾

首先来回顾一下位运算,什么是位运算呢?

位运算就是直接对整数在内存中的二进制位进行操作。

在 Java 语言中,位运算有如下这些:

左移(<<)。右移(>>)。无符号右移(>>>)。与(&)。或(|)。非(~)。异或(^)。

在本篇文章中,我们所需要用到的有如下几个(其他的后续文章再讲):

&(与运算):只有当两方都为 true 时,结果才是 true,否则为 false。|(或运算):只要当一方为 true 时,结果就是 true,否则为 false。^(异或运算):只要两方不同,结果就是 true,否则为 false。

以 true、false 为例:

true & true = truetrue & 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 00000000 0000 0000 00010000 0000 0000 00100000 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_OPTIMISTICmStatus |= STATUS_OPEN

存储完后,mStatus的二进制为:

00000011

再来取出STATUS_OPEN这个状态:

mStatus ^= STATUS_OPEN

运算过程:

0000001100000010-----------00000001

mStatus现在就只有STATUS_OPTIMISTIC的状态了。

总结

通过 |、^、& 运算,我们可以很方便快捷的对状态值进行操作。当然,位运算的应用不仅限于状态值,知道了其中的二进制运算原理后,还有更多的其他应用场景,等着你去发现。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。