Java中的运算符分为四类:
算数运算符:+ - * / % ++ --
关系运算符:> >= == <= < !=
逻辑运算符:&& & || | ! ^
位运算符:& | ~ ^ >> << >>>
算数运算符和关系运算符比较简单不进行赘述了!~~~
逻辑运算符:
注意:逻辑运算符操作的都是boolean类型的变量,而且结果也是boolean类型
&&和&,表示当且仅当公式两边都为true时,结果为true,&&表示短路与、&表示逻辑与,区别在于逻辑与两边的公式都会校验,而短路与当左边的公式为false时不再校验右边的公式了
||和|,表示当且仅当公式两边都为false时,结果为false,||表示短路或、|表示逻辑或,区别同上
!,表示逻辑非
^,表示逻辑异或,公式两边为异时,结果为true
a | b | a&&b | a&b | a||b | a|b | !a | a^b |
---|---|---|---|---|---|---|---|
true | false | false | false | true | true | false | true |
true | true | true | true | true | true | false | false |
位运算符:重点
^,表示位运算的异或,异或运算方式是一个二进制运算,1^0=1、1^1=0、0^0=0,两者相等为0不等为1。
异或的运算法则:
- a ^ b = b ^ a
- a ^ b ^ c = a ^ (b ^ c) = (a ^ b) ^ c
- d = a ^ b ^ c 可以推出 a = d ^ b ^ c
- a ^ b ^ a = b
- a ^ a = 0
- a ^ 0 = a
场景一、交换两个变量的值(a = 10、b = 20)?
通常情况下需要一个辅助变量进行协助,但是通过异或运算可以避免:
a = a ^ b;
b = a ^ b;
a = a ^ b;
解析:第一步不多说看第二步:b = a ^ b,这个公式可以推导:b = a ^ b ^ b,结合律推导:b = a ^ (b ^ b) --> b = a ^ 0 --> a
场景二、对于一个有多个数值的数组(a[]),只有一个是唯一的,其他都是成对的,怎样快速找到这个唯一值?
如果我们了解异或是不是很简单?结果 = a[0]^a[1]^a[2]^.....^a[n];
为啥?a ^ a = 0、a ^ 0 = a,比如:1,2,3,2,3,1 ^ 2 ^ 3 ^ 2 ^3 = 1 ^ ( 2 ^ 2 ) ^ ( 3 ^ 3 ) = 1 ^ 0 ^ 0 = 1
&,表示位运算的与,一种二进制运算,符号两边都为1才为1
场景一、判断奇偶数?
分析:奇数都不是2的整数倍,转换成二进制后最低位必然为1,偶数则相反。利用这个特性我们可以很容易的通过位运算判断一个整数的奇偶性。比如:
int i = 1;// 二进制存储方式为00000000000000000000000000000001
int j = 5;// 二进制存储方式为00000000000000000000000000000101
int k = 6;// 二进制存储方式为00000000000000000000000000000110
if ((i & j) == 1) {
System.out.println("j的最低位为1,为奇数");
}
if ((i & k) == 0) {
System.out.println("k的最低位为0,为偶数");
}
<<, 表示左位移,一种二进制运算,二进制值整体左移且低位补0, 2 << 3 = 16
>>,表示右位移,一种二进制运算,二进制值整体右移且溢出去掉,16 >> 2 = 4
>>>,表示无符号右位移,一种二进制运算,忽略符号位,空位都以0补齐
|,表示或,一种二进制运算,符号两边全为0时结果为0,其他为1