操作一
- 当我们需要用一个变量保存多个状态值时,我们可以会使用逗号隔开的字符串表示:
String str = "1,2,3,4";
- 这里说一种使用位运算计算的Integer值来表示:
public static void main(String[] args) {
int value = buildValue(1)
+ buildValue(2)
+ buildValue(3)
+ buildValue(4);
System.out.println(value );
System.out.println(value & buildValue(1));
System.out.println(value & buildValue(2));
System.out.println(value & buildValue(3));
System.out.println(value & buildValue(4));
}
private static Integer buildValue(Integer param) {
return 1 << (param - 1);
}
- 上面例子中对参数1,2,3,4都进行对应的位运算 1 << (n - 1);其表示2^(n-1)。得出的值分别为1,2,4,8。其相加的值为15。在通过按位与运算,可以得出当前参数是否存在value中。这里需要了解&按位与运算方式。
- 由1 2 4 8相加的结果对1 2 4 8进行&运算:
描述 | 二进制(十进制) | 二进制(十进制) | 二进制(十进制) | 二进制(十进制) |
---|
累加值 | 01111(15) | 01111(15) | 01111(15) | 01111(15) |
验证值 | 00001(1) | 00010(2) | 00100(4) | 01000(8) |
结果 | 00001 | 00010 | 00100 | 01000 |
- 由2 4 8相加的结果对1 2 4 8进行&运算:
描述 | 二进制(十进制) | 二进制(十进制) | 二进制(十进制) | 二进制(十进制) |
---|
累加值 | 01110(14) | 01110(14) | 01110(14) | 01110(14) |
验证值 | 00001(1) | 00010(2) | 00100(4) | 01000(8) |
结果 | 0 | 00010 | 00100 | 01000 |
- 由1 4 8相加的结果对1 2 4 8进行&运算:
描述 | 二进制(十进制) | 二进制(十进制) | 二进制(十进制) | 二进制(十进制) |
---|
累加值 | 01101(13) | 01101(13) | 01101(13) | 01101(13) |
验证值 | 00001(1) | 00010(2) | 00100(4) | 01000(8) |
结果 | 00001 | 0 | 00100 | 01000 |
描述 | 二进制(十进制) | 二进制(十进制) | 二进制(十进制) | 二进制(十进制) |
---|
累加值 | 01100(12) | 01100(12) | 01100(12) | 01100(12) |
验证值 | 00001(1) | 00010(2) | 00100(4) | 01000(8) |
结果 | 0 | 0 | 00100 | 01000 |
- 规则总结:只有两个操作数对应位同为1时,结果为1,其余全为0. (或者是只要有一个操作数为0,结果就为0)。
- 使用优势:减少数据资源占用;计算机使用位运算效率会很快;
- 缺点:可读性不足,无法直接明确的知晓参数意义;不能对重复的值进行添加操作,否则会打乱其结果。
- 场景
- 使用1 << (n - 1)计算值想得到正数那么n最大值为31,而31代表一个月最多的天数。所以针对自然月内天数的数据可以用这种方式进行存储数据(我之前公司就是使用这种方式解决了一个实际业务场景);
- 可以针对叠加状态,累计操作等等实际业务都可以使用这种整型数据存储(根据实际业务使用)。
操作二
public static void main(String[] args) {
Integer[] arr = {2, 3};
int ii = arr[0];
arr[0] = arr[1];
arr[1] = ii;
System.err.println(Arrays.toString(arr));
}
---------------------------------------------
结果:[3, 2]
public static void main(String[] args) {
Integer[] arr = {2, 3};
arr[1] = arr[0] ^ arr[1];
arr[0] = arr[0] ^ arr[1];
arr[1] = arr[0] ^ arr[1];
System.err.println(Arrays.toString(arr));
}
---------------------------------------------
结果:[3, 2]
- ^ 异或运算:两个数值进行比对,两个数值中,相同的位都为0或者都为1(即相同位值相同),则结果数值中对应的位则为0,不同,则结果数值中对应的位就为1;
- 第一步arr[1] = arr[0] ^ arr[1]运算的过程和结果:
描述 | 二进制(十进制) |
---|
arr[0] | 010(2) |
arr[1] | 011(3) |
运算结果 | 001(1) |
数组结果 | {2,1} |
- 第二步arr[0] = arr[0] ^ arr[1]运算的过程和结果:
描述 | 二进制(十进制) |
---|
arr[0] | 010(2) |
arr[1] | 001(1) |
运算结果 | 011(3) |
数组结果 | {3,1} |
- 第三步arr[1] = arr[0] ^ arr[1]运算的过程和结果:
描述 | 二进制(十进制) |
---|
arr[0] | 011(3) |
arr[1] | 001(1) |
运算结果 | 010(2) |
数组结果 | {3,2} |
- 所以最后的结果是{3,2}。数组内元素替换了位置。