我不去想是否能够成功
既然选择了远方
便只顾风雨兼程
—— 汪国真
目录
1. 认识运算符
1.1 认识运算符
1.2 运算符的分类
2. 算术运算符
2.1 四则运算符
2.2 复合赋值运算符
2.3 自增 / 自减 运算符
3.关系运算符
4.逻辑运算符
4.1 逻辑与 &&
4.2 逻辑或 ||
4.3 逻辑非 !
4.4 短路求值
4.5 记忆口诀
5.位运算符
5.1 按位与 &
5.2 按位或 |
5.3 按位取反 ~
5.4 按位异或 ^
6.移位运算
6.1 左移 <<
5.2 右移 >>
5.3 无符号右移 >>>
6.条件运算符
运算符:对操作数进行操作时而用到的符号就叫做运算符(最常见的的操作便是进行数学运算),比如:+ - x / 都是运算符。
public class Test {
public static void main(String[] args) {
int a = 1;// = :是赋值运算符
int b = 2;
int c = 1 + 2;// + :算术运算符
System.out.println(c);
}
}
上述代码中 = 和 + 就是运算符,即:对操作数进行操作时的符号就是运算符,不同运算符操作的含义不同。
四则运算符:+ - * / %
四则运算符 是 双目运算符
补充知识:
- 双目运算符:有两个操作数的就叫做双目运算符
- 单目运算符:有一个操作数的就叫做单目运算符
四则运算符两边操作数可以是变量也可以是常量
① + - * /
public class Test {
public static void main(String[] args) {
int a = 1;
int b = 2;
System.out.println(a + b);
System.out.println(a - b);
System.out.println(a * b);
System.out.println(a / b);
System.out.println(1 + 2);
}
}
a / b:int / int = int,如果我们想要得到小数,有两种方法
方法一:强制类型转换法
public class Test {
public static void main(String[] args) {
int a = 1;
int b = 2;
System.out.println((double) a / b);
}
}
首先将 a 强制类型转换为 double 类型,然后除 b,当 b 看到 a 是 double 类型,则会自动提升成double 类型
方法二:乘小数法
public class Test {
public static void main(String[] args) {
int a = 1;
int b = 2;
System.out.println((a * 1.0) / b);
}
}
首先我们知道 一个数 乘 1 等于这个数本身,a * 1.0 此时相当于 int * double = double ,a * 1.0的结果是 double 类型的,然后在除 b,就相当于 double / int = double
在做除法运算的时候右操作数不能为 0
② %
public class Test {
public static void main(String[] args) {
System.out.println(7 % 2);
System.out.println(-7 % 2);
System.out.println(7.5 % 2);
}
}
运行结果 :
取余算法:
注:Java中的取余运算符左右两边操作数可以浮点数,但是C语言中取余运算符左右两边操作数必须是整数
在做取余运算的时候右操作数不能为 0
复合赋值运算符:+= -= *= /= %= <<= 等等
复合赋值运算符作用:将操纵的结果赋值给左操作数。比如:(a = 1;) a += 7; 相等于 a = a + 7;
public class Test {
public static void main(String[] args) {
int a = 1;
a += 6;//等价于 a = a + 6 ,a = 7
System.out.println(a);
a -= 1;//等价于 a = a - 3 ,a = 6;
System.out.println(a);
a /= 2;//等价于 a = a / 2 ,a = 3;
System.out.println(a);
a *= 7;//等价于 a = a * 3 ,a = 21;
System.out.println(a);
a %= 5;//等价于 a = a % 3 ,a = 1;
System.out.println(a);
a += 7 + 1;//等价于 a = a + (7 + 1) ,a = 9;
System.out.println(a);
}
}
注:复合赋值运算符左操作数必须是变量,因为常量不允许被修改
当不同类型使用复合赋值运算符是会自动发生类型转换,不需要我们自己强制转换
public class Test {
public static void main(String[] args) {
int a = 1;
a += 1.5;//等价于:a = (int)(a + 1.5)
System.out.println(a);
}
}
自增 / 自减 运算符 :++ --
自增 / 自减 运算符的作用:对变量的值进行 加一 或 减一
自增可以分为 前置++ 和 后置++
自减可以分为 前置-- 和 后置--
public class Test {
public static void main(String[] args) {
int a = 9;
System.out.println(++a);//先将a的值加一(a = 10),然后在打印。打印结果为:10
System.out.println(a++);//先将a的值打印,然后在加一(a = 11)。打印结果为:10
System.out.println(--a);//先将a的值减一(a = 10),然后在打印。打印结果为:10
System.out.println(a--);//先将a的值打印,然后在减一(a = 9)。打印结果为:10
}
}
虽然 ++a ,看似没有给 a 赋值,但是 a 中的值依然会 +1
自增 / 自减 运算符看似没有给变量赋值,但是变量中的值依然发改变
注:只有变量才能使用自增/自减运算符,常量不能使用,因为常量不允许被修改
关系运算符:> < >= <= != ==
关系运算符的作用:用于判断是否为 true 或者是 false
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a > b);//10 > 20 为假,打印false
System.out.println(a >= b);//10 >= 20 为假,打印false
System.out.println(a < b);//10 < 20 为真,打印true
System.out.println(a <= b);//10 <= 20 为真,打印true
System.out.println(a != b);//10 != 20 为真,打印true
System.out.println(a == b);//10 == 20 为假,打印false
System.out.println(1 > 2);//1 > 2为假,打印false
System.out.println(1 < 2);//1 < 2为真,打印true
}
}
逻辑运算符:&& || !
逻辑运算符的作用 :用于判断是否为 true 或者是 false
&&: 双目运算符,左右两边都是表达式,表达式的结果都是 boolean 类型
&&语法规则:表达式1 && 表达式2,表达式1结果为true , 表达式2 结果为true,整个表达式的结果才为true
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 30;
System.out.println(a < b && c > b);//true && true,打印true
System.out.println(a < b && c < b);//true && false,打印false
System.out.println(a > b && c > b);//false && true,打印false
System.out.println(a > b && c < b);//false && false,打印false
}
}
注:boolean 类型只有两个值,一个是true ,还有一个是 false
||:双目运算符,左右两边都是表达式,表达式的结果都是 boolean 类型
|| 语法规则:表达式1 || 表达式2,表达式1结果 或者 表达式2结果 至少有一个为为true,整个表达式的结果才为true
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 30;
System.out.println(a < b || c > b);//true || true,打印true
System.out.println(a < b || c < b);//true || false,打印true
System.out.println(a > b || c > b);//false || true,打印true
System.out.println(a > b || c < b);//false || false,打印false
}
}
!:单目运算符,只有一个操作数。表达式的结果都是 boolean 类型
!语法规则:!(表达式),表达式的结果为为 true,则整个表达式的结果就为 false;表达式的结果为 false,则整个表达式的结果就为false
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(!(a > b));//10 > 20,结果为false,然后经过逻辑非结果就是true
System.out.println(!(a < b));//10 > 20,结果为true,然后经过逻辑非结果就是false
}
}
对于 && 和 || ,都是遵循短路求值规则
① && 的短路求值
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println((a > b) && ((++a) > b));
System.out.println(a);
}
}
上述代码运行结果:
代码解析:
&& 两边操作数都为真,结果为真;要是有一个结果为假,则结果为假。 当执行 表达式1 时发现为假,则整个表达式的结果为假。如果为真,则继续判断下一个 表达式2 的结果 ,表达式2 的结果为真,则整个表达式的结果为真,如果 表达式2 的结果为假,则整个表达式的结果为假
a > b ----> 10 > 20 ,表达式为假,则不会执行(++a)> b。所以整个表达式的结果为假,并且 a 的值不变
② || 的短路求值
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println((a < b) || ((++a) < b));
System.out.println(a);
}
}
上述代码运行结果:
代码解析:
|| 两边操作数的结果至少有一个为真,则整个表达式为真;都为假,则整个表达式为假 。当执行表达式1 的时候如果结果为真,则不会去执行 表达式2 ,整个表达式的结果就为真。当执行 表达式1 的时候,如果结果为假,则去执行 表达式2 ,表达式2 的结果为真,则整个表达式的结果就为真,要是 表达式2 的结果为假,则整个表达式的结果为假
&&:全真得真
||:见真得真
! : 非真即为假,非假即为真
位运算符,见名知意 就可以知道是处理二进制位的运算符。
补充知识:
Java 中数据存储的最小单位是字节,而数据操作的最小单位是比特位
1 字节 = 8 比特位
位操作表示 按二进制位运算. 计算机中都是使用二进制来表示数据的(二进制:01构成的序列), 按位运算就是在按照 二进制位 的每一位依次进行运算。
位运算符:& | ~ ^
注:位运算符操作数可以是变量也可以是常量
&:全一得一,两个比特位都是 1 ,则为 1
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a & b);
System.out.println(7 & 6);
}
}
上述代码运行结果:
代码分析:
a = 10,b = 20,然后 a & b。 首先将 a 和 b 都转换成二进制的形式,因为 a,b 是 int 类型所以转换为 32 位二进制位:
a:00000000 00000000 00000000 00001010
b:00000000 00000000 00000000 00010100
然后进行按位与,全一得一,则结果为:
00000000 00000000 00000000 00000000,结果就为 0
7 & 6, 7 和 6 默认都是 int 类型的,首先将 7 和 6 都转换为 32 位二进制位:
7:00000000 00000000 00000000 00000111
6:00000000 00000000 00000000 00000110
然后进行按位与,全一得一,则结果为:
00000000 00000000 00000000 00000110 ,就为 6
| :见一得一,两个比特位只要有一个是 1 ,则为 1
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a | b);
System.out.println(7 | 6);
}
}
上述代码运行结果:
代码解析:
a = 10,b = 20,然后 a | b。 首先将 a 和 b 都转换成二进制的形式,因为 a,b 是 int 类型所以转换为 32 位二进制位:
a:00000000 00000000 00000000 00001010
b:00000000 00000000 00000000 00010100
然后进行按位与,见一得一,则结果为:
00000000 00000000 00000000 00011110,结果就为 30
7 & 6, 7 和 6 默认都是 int 类型的,首先将 7 和 6 都转换为 32 位二进制位:
7:00000000 00000000 00000000 00000111
6:00000000 00000000 00000000 00000110
然后进行按位与,见一得一,则结果为:
00000000 00000000 00000000 00000111 ,就为 7
~ : 1 变 0 , 0 变1
public class Test {
public static void main(String[] args) {
int a = 10;
System.out.println(~a);
}
}
上述代码运行结果:
代码解析:
a = 10,然后 ~a 。 首先将 a 转换成二进制的形式,因为 a 是 int 类型所以转换为 32 位二进制位:
a:00000000 00000000 00000000 00001010
然后按位取反得,1 变 0 , 0 变 1,得:
11111111 11111111 11111111 11110101
计算机只会存储二进制补码的形式,所以计算机会认为这是补码,在用户进行读取的时候计算机会自动将补码转换成原码,然后进行读取出来
补码转原码有两种方法
方法一:补码除了符号位,其他位按位取反,然后加1,的原码
方法二:补码减一得反码,反码符号位不变其他位按位取反得原码
则 ~a 的结果就是 -11
补充知识:
正数的原 反 补相同
负数的反码等于原码符号位不变,然后按位取反;负数的补码就是负数的反码加1
^ :相同为 0,不同为 1
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a ^ b);
}
}
上述代码运行结果 :
a = 10,b = 20,然后 a ^ b。 首先将 a 和 b 都转换成二进制的形式,因为 a,b 是 int 类型所以转换为 32 位二进制位:
a:00000000 00000000 00000000 00001010
b:00000000 00000000 00000000 00010100
然后进行按位异或,相同为 0,不同为 1 则结果为:
00000000 00000000 00000000 00011110,结果就为 30
移位运算符,见名知意 肯定又是对二进制位的运算
移位运算符:<< >> >>>
<< :最左侧位不要了, 最右侧补 0
public class Test {
public static void main(String[] args) {
int a = 10;
System.out.println(a << 1);
}
}
上述代码运行结果:
代码解析:
a = 10,然后 a << 1 。 首先将 a 转换成二进制的形式,因为 a 是 int 类型所以转换为 32 位二进制位:
a:00000000 00000000 00000000 00001010
然后最左侧位不要了, 最右侧补 0
00000000 00000000 00000000 00010100
将二进制位转换为十进制就是 20
注:
>>:最右侧位不要了, 最左侧补符号位(正数补0, 负数补1)
public class Test {
public static void main(String[] args) {
int a = 10;
System.out.println(a >> 1);
}
}
上述代码运行结果:
代码解析:
a = 10,然后 a >> 1 。 首先将 a 转换成二进制的形式,因为 a 是 int 类型所以转换为 32 位二进制位:
a:00000000 00000000 00000000 00001010
然后最右边侧位不要了, 左边正数补0, 负数补1
00000000 00000000 00000000 00001010
将二进制位转换为十进制就是 20
注:右移 1 位, 相当于原数字 / 2. 右移 N 位, 相当于原数字 / 2 的N次方.
>>>:最右侧位不要了, 最左侧补 0
public class Test {
public static void main(String[] args) {
int a = -10;
System.out.println(a >>> 1);
}
}
上述代码运行结果:
代码解析:
a = -10,然后 a >>> 1 。 首先将 a 转换成二进制的形式,因为 a 是 int 类型所以转换为 32 位二进制位:
a:10000000 00000000 00000000 00001010
如果是负数,则需要转为补码然后存储在计算机内进行运算
原码:10000000 00000000 00000000 00001010
反码:11111111 11111111 11111111 11110101
补码:11111111 11111111 11111111 11110110
然后无符号左移: 01111111 11111111 11111111 11111011
结果就为:2147483643
条件运算符只要一个:?:
条件运算符的格式:表达式1 ? 表达式2 : 表达式3
表达式1 的结果必须是 boolean 类型
当 表达式1 的值为 true 时, 整个表达式的值为 表达式2 的值; 当 表达式1 的值为 false 时, 整个表达式的值为 表达式3 的值.
条件运算符也是 Java 中唯一的一个 三目运算符, 是条件判断语句的简化写法.
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = (a > b) ? a : b;
System.out.println(c);
}
}
上述代码运行结果:
代码解析:
如果 a > b 为 true ,则把 a 的值赋值给 c,如果 a > b 为 false ,则把 b 的值赋值给 c