- 今天重温的主要是Java运算符,在这里我把之前已经遗忘的一些点记录下来,以后回顾的时候可以翻阅。
比较运算符
^异或:
- 符号两边的结果相同为False,不同则为True
1
2
3
4True ^ True = False ;
False ^ True = True ;
True ^ False = True ;
False ^ False = False ;
!非:
- 两次非运算就是原数
1
2!true = false ;
!!true = true ;
逻辑运算符
&和&&的区别:
让我们先来看一段代码
1
2
3int x = 1;
if(x>2 && x<5)
System.out.println();在上面的情况中,在对 && 左边的式子进行判断后,得出左边的式子值是false,因为两数相与,只要有一个flase,整体式子的结果就是false。所以停止运算右侧式子,直接给出false的结果。
但是使用 & 运算符的时候,无论左边式子是什么,右边都参与运算。
&& 和 & 运算结果一样,过程有一些小区别
& :无论左边式子是什么,右边都参与运算
&& :当式子左边为false时,右边不参与运算,结果为false
|和||的区别
- 上面我们说了 & 和 && 的区别,其实原理是一样的
- || 和 | 运算结果一样,过程有一些小区别
| :无论左边式子是什么,右边都参与运算
|| :当式子左边为true时,右边不参与运算,结果为true
位运算
& 位运算
下面我用一个小例子来演示
1
2
3
4
5
6
76 & 3 = ?
内存中
0000-0000 0000-0000 0000-0000 0000-0110
& 0000-0000 0000-0000 0000-0000 0000-0011
-----------------------------------------
0000-0000 0000-0000 0000-0000 0000-0010
∴ 6 & 3 = 26 & 3 在内存中变化的实质是,转换为2进制,各位相对应的进行 & 运算
应用场景:
取0100 0000 1100 0101的后四位,如何进行操作?
答 :用0000 0000 0000 1111与其进行 & 运算。
| 位运算
- 原理同上 例如 6 | 3 = 7
^ 位运算
原理同上
1
2
3
4
5
6
7
8
9
10
11
126 ^ 3 = ?
内存中(简化)
0110
^ 0011
------
0101
∴ 6 ^ 3 = 5
继续 ^ 3
5 ^ 3 = ?
演算后
5 ^ 3 = 6不知道大家发没发现这个运算的一些小秘密,那就是一个数连续两次与相同的数进行异或运算后,结果会是最初的数。用公式写就是: a ^ b ^ b = a
- 那么这个究竟可以用作干什么那?可以用于文件的加密!
~ 反码
大家可以在自己的电脑上试一下下面的代码,看看是不是自己猜测的值
1
2int a = 2;
System.out.println(~a);结果是 -3 ,很多人可能都以为反码的意思就是将a的二进制10取反为01,猜测结果是1
- 为什么不是这样的运算过程那?
原理
这就要从计算机常用的几个码说起了。首先,java存储的是有符号数,在计算机中,有符号数通常是使用补码存储的,java也不例外。先来看看什么叫原码,反码,补码。
原码
原码就是符号位加上真值的绝对值,即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:1
[+1]原 = 0000 0001
反码
正数的反码是其本身
负数的反码是在其原码的基础上,符号位不变,其余各个位取反.
例如:1
[+1] = [00000001]原 = [00000001]反
补码
正数的补码就是其本身
负数的补码是在反码的基础上+1。
例如:1
[+1] = [00000001]原 = [00000001]反 = [00000001]补
分析
所以回到一开始的问题,int a = 2 a在计算机中是以补码存储的。
- 对于2这个正数来说,补码、反码、原码都是相同的,又由于是数值型,在这里我先用八位bit来表示一下:
1
2原码:0000 0010
反码:0000 0010
补码:0000 0010
取反
取反过程是在补码的基础上进行的,由于是按位取反,无论符号位还是数值位都要取反,所以结果如下:1
取反后的补码: 1111 1101
换算为值
那么取反后的补码的实际值是多少呢?我们需要先把他转化为原码,过程如下:1
反码 = 1111 1101 - 1 = 1111 1100
原码 = 反码符号位不变,其余取反 = 1000 0011
所以,最后的值-3
<< 左移
这个符号之前并没有听说过,在这次学习中进行了掌握(开始我还以为是C++的cout那)
1
2
3
4
5
63 << 2 = ?
内存中
0000-0000 0000-0000 0000-0000 0000-0011
结果
0000-0000 0000-0000 0000-0000 0000-1100
∴ 3 << 2 = 12上面的运算实质是 3的2进制 整题左移两位,多余的舍弃,空位用0补
- 一个数进行左移运算时,左移n位,即是该数乘以2的n次幂
>> 右移
- 原理几乎一样,只有略微的不同
原来最高位是什么,用什么补空位(因为最高位为1时是负数) - 右移n位,即是该数除以2的n次幂
1
2
3
4-12 >> 2 = ?
答: -3
12 >> 2 = ?
答: 3
>>> 无符号右移
- 高位空位,全部填0,用0补位
1
2
3
4-12 >>> 2 = ?
答: 3
12 >>> 2 = ?
答: 3
应用
请用效率最高的方法求出 2*8 的值。
1
System.out.println(2<<3);
两个整数值互换(不使用第三方变量)
1
2
3
4
5
6
7
8
9
10
11方法1:(不建议使用,如果数值过大,可能丢失精度)
int a = 3, b = 5;
a = a + b;
b = a - b;
a = a - b
方法2:(利用异或位运算)
int a = 3, b = 5;
a = a ^ b;
b = a ^ b;
a = a ^ b;
三元运算符
- (条件表达式)?表达式1:表达式2
- 若条件为true ,结果为表达式1
若条件为false,结果为表达式21
2
3
4练习:在x , y中取 值较大的整数
int x = 3, y = 4;
int max = ( x>y )? x : y;
System.out.println(max);
swich 和 if else 与 三元运算符
三元运算符必须有结果,if else可有,可不有结果。当if else有具体运算结果时,可以使用三元运算符。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17swich使用示范:
int x = 3;
swich(x)
{
case 1:
System.out.println(x);
break;
case 2:
System.out.println(x);
break;
case 3:
System.out.println(x);
break;
case default:
System.out.println(x);
break;
}if:
对几个具体值进行判断 对区间判断 对运算结果boolean类型表达式判断
swich:
对几个具体值进行判断 值的个数通常是固定的
- 对几个固定值判断,建议使用swich,swich将答案存在内存中,效率高