review

So let’s start with a bit operation, what is a bit operation?

Bitwise operations operate directly on the binary bits of an integer in memory.

In the Java language, bit operations are as follows:

  • Move left (<<).

  • Move right (>>).

  • Unsigned move right (>>>).

  • And (&).

  • Or (|).

  • Not (~).

  • Xor (^).

In this article, we need to use a few of the following (to be covered in a future article) :

  • & (and operation) : The result is true only if both sides are true, otherwise false.

  • | (or operation) : when a party to true, the result is true, false otherwise.

  • ^ (xor operation) : as long as the two sides are different, the result is true, otherwise false.

Take true and false as examples:


true & true  = true

true & false = false



true | false = true;

false | false = false;



true ^ true = false;

true ^ false = true;

Copy the code

Take number crunching:

6 &4 =? 6 | 4 =? 6 to the fourth is equal to?Copy the code

When working with numbers, we first need to know the binary values of the numbers. Assuming 6 is an int, the binary values are as follows:


00000000 00000000 00000000 00000110

Copy the code

In Java, ints are four bytes, and one Byte is eight bits. So the binary representation of int is shown above.

Here for the convenience of explanation, directly take the last 8 bits: 00000110.

The binary code of 4 is as follows:


00000100

Copy the code

In binary code, 1 is true and 0 is false.

00000110, 00000100 -- -- -- -- -- -- -- -- -- -- - 00000100Copy the code

The result of the operation on each digit is 4.

Take a look at | operation:

6 | 4 =?Copy the code

The binary of 6 and 4 has been stated above:

00000110, 00000100 -- -- -- -- -- -- -- -- -- -- - 00000110Copy the code

You can see that the final result is 6.

Finally, let’s look at ^ :

6 to the fourth is equal to?Copy the code
00000110, 00000100 -- -- -- -- -- -- -- -- -- -- - 00000010Copy the code

So that’s 2.

application

Through the above example, we have reviewed the &, | and ^ operation. Now let’s put it into practice.

If we were to define a model of a person now, this person might include a variety of characteristics, such as optimistic, introverted…

If we want to know what kind of personality he contains, then how do we judge?

Your first thought might be:


if(This person is optimistic){.... }else if(This person is introverted){... }Copy the code

What if there are multiple personalities? A bunch of judgments are really killing to write…

Here’s an easier way to do it. Let’s first define a set of numbers:


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;
Copy the code

Convert them to binary:

0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100Copy the code

Do you see any binary patterns? Both are powers of two, and only one binary is 1 bit, and all the others are 0!

We then define a variable to store the state (default is 0) :


private static int mStatus = STATUS_NORMAL;
Copy the code

When we want to save the state, with | operation can be directly:


mStatus |= STATUS_OPTIMISTIC;
Copy the code

The saved operation process is as follows:

00000000 | operation performed (as long as there is 1 to 1), 00000001 -- -- -- -- -- -- -- -- -- -- -- 00000001 = 1Copy the code

So we’re just storing this one in the binary of the zero.

So what if you want to determine if there’s a state in mStatus? Use & :

System.out.println((mStatus & STATUS_OPTIMISTIC) ! = 0); //true, means have itCopy the code

The calculation process is as follows:

00000001 Perform the & operation (1 only if the value is both 1) 00000001 ----------- 00000001 = 1Copy the code

MStatus & STATUS_OPEN:

System.out.println((mStatus & STATUS_OPEN) ! = 0); //false, means no itCopy the code

The calculation process is as follows:


    00000001

    00000010

    -----------

    00000000 = 0

Copy the code

Since the binary bits of the STATUS_OPEN state are 0, the binary bits of mStatus do not match 1, and all other bits are 0, so the calculated result is 0.

That’s why the numbers that define the states are 1, 2, and 4, because they’re specific because there’s only one 1 bit in binary, and all the other bits are zeros, and they don’t conflict with the other 1 bits.

If I had a different number, I would have a problem. For example, 3:


mStatus |= 3

Copy the code

Calculation process:


    00000000

    00000011

    -----------

    00000011 = 3

Copy the code

MStatus = 3; mStatus = 2; mStatus = 3;

System.out.println((mStatus & 2) ! = 0); //true"Means there is it, but there isn'tCopy the code

    00000011

    00000010

    -----------

    00000010 = 2

Copy the code

The result is true, but in fact we only stored 3 in mStatus, so the result must be wrong.

So when we are defining, we must not slip to define the wrong number.

Storage and judgment, so how do you get it out? That’s where the ^ operation comes in.

If the STATUS_OPTIMISTIC status is stored in mStatus, you can retrieve it by writing:


mStatus ^= STATUS_OPTIMISTIC

Copy the code

The operation process:

00000001 If the two sides are different, perform the ^ operationtrue00000001 -- -- -- -- -- -- -- -- -- -- - 00000000Copy the code

You can see that the state is back to the original time when STATUS_OPTIMISTIC state was not stored.

Finally, let’s look at an example of fetching, this time storing two states and then fetching one of them:


mStatus |= STATUS_OPTIMISTIC

mStatus |= STATUS_OPEN

Copy the code

After storage, the binary of mStatus is:


00000011

Copy the code

Return STATUS_OPEN:


mStatus ^= STATUS_OPEN

Copy the code

Operation process:

00000011, 00000010 -- -- -- -- -- -- -- -- -- -- - 00000001Copy the code

MStatus now has only a STATUS_OPTIMISTIC state.

conclusion

Through |, ^, & operation, we can be very convenient for operating status value. Of course, bitwise operations are not limited to state values, but once you know how binary operations work, there are many other applications waiting to be discovered.