java中提供的基础位运算符有 与(&),或(|),非(~),异或(^),左移<<,右移(>>)和无符号右移(>>>)
除了位非(~)是一元操作符外,其它的都是二元操作符
异或运算满足 交换律 和 结合律,①0 ^ N == N ② N ^ N == 0
为什么右移有“有无”符号之别,而左移却没有?(留个尾巴,后续补充)
/**
* 利用位的异或运算进行交换操作
*/
public static void swap(){
int a = 23;
int b = 45;
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println("a:"+a+"====b:"+b);
}
public static void findOneAppearOdd(){
int[] arr = {2,3,4,3,4,2,2,7,2,5,6,6,5};
int result = 0;
//将数组中所有的数都进行异或,那些出现偶数次的数字就抵消掉了
for(int i=0; i<arr.length; i++){
result ^= arr[i];
}
System.out.println("数组中出现奇数次的一种数为:"+result);
}
public static void findTwoAppearOdd(){
int[] arr = {2,3,4,3,4,2,2,7,2,5,6,6,5,8};
int result = 0;
//将数组中所有的数都进行异或,那些出现偶数次的数字就抵消掉了
for(int i=0; i<arr.length; i++){
result ^= arr[i];
}
//查找result最右边为1的数字
int rightOne = result & (~result + 1);
int oneTarget = 0;
for(int i=0; i<arr.length; i++){
if((rightOne & arr[i]) > 0){
oneTarget ^= arr[i];
}
}
int anotherTarget = result ^ oneTarget;
System.out.println("查找结果为:"+oneTarget +"======="+ anotherTarget);
}
/**
* 校验一个数是否为2的整数次幂
* @param a
* @return
*/
private static boolean check2Pow(int a) {
//去掉最右侧的1以后,理论上该变为0的
return (a & (a-1)) == 0;
}
/**
* 位操作统计二进制中 1 的个数
* @param m
* @return
*/
private static int getNumOfOne(int m){
int count = 0;
while(m > 0){
//该操作会卸下m最右侧的1
m = m & (m-1);
count++;
}
return count;
}
public class BitMapUtil {
/**
* 加上某一个位上的值
* @param value
* @param bitValue
* @return
*/
public static int addFlag(int value, int bitValue){
if(checkFlag(value, bitValue)){
return value;
}
return value | bitValue;
}
/**
* 移除某一位上的值
* @param value
* @param bitValue
* @return
*/
public static int removeFlag(int value, int bitValue){
if(!checkFlag(value, bitValue)){
return value;
}
return value ^ bitValue;
}
/**
* 校验某一个位上是否有值
* @param value
* @param bitValue
* @return
*/
public static boolean checkFlag(int value, int bitValue){
return (value & bitValue) > 0 ;
//return (value & bitValue) == bitValue ;
}
}