一、什么是运算符
运算符是一种特殊的符号,用来表示数据的运算、赋值和比较。大致可以分为以下六类:算术运算符、赋值运算符、关系运算符、逻辑运算符、位运算符以及三元运算符。
二、算术运算符
运算符 | 运算 | 示例 | 结果 |
+ | 正号 | +7 | 7 |
- | 负号 | b=11;-b | -11 |
+ | 加 | 9+9 | 18 |
- | 减 | 10-8 | 2 |
* | 乘 | 7*8 | 56 |
/ | 除 | 9/9 | 1 |
% | 取模 | 11%9 | 2 |
++ ++ | 自增(前):先运算后取值 自增(后):选取值后运算 | a=2;b=++a; a=2;b=a++ | a=3;b=3; a=3;b=2; |
-- -- | 自减(前):先运算后取值 自减(后):先取值后运算 | a=2;b=--a; a=2;b=a--; | a=1;b=1; a=1;b=2; |
+ | 字符串相加 | "Clear"+"Love" | "ClearLove" |
2.1取模运算
在Java中,取模运算就是求余数。实际上,以a%b为例,取模运算是这样在计算机中进行运算的:a % b = a - (a / b) * b。看下面这个例子:
int k1 = (-10)%3;
int k2 = 10%(-3);
int k3 = (-10)%(-3);
System.out.println(k1);//(-10)-(-10/3)*3=(-10)-(-3)*3=-1;
System.out.println(k2);//10-(10/-3)*(-3)=10-(-3)*(-3)=1
System.out.println(k3);//(-10)-(-10/-3)*(-3)=(-10)-3*(-3)=-1;
2.2自增自减运算
自增自减运算在独立使用时没有任何区别。
int a=0,b=0;
a++;//等价于a = a + 1;
++b;//等价于b = b + 1;
System.out.println(a);//1
System.out.println(b);//1
做表达式使用时:前缀++表示先自增后赋值,后缀++表示先赋值后自增。
int k = 0;
int i = k++;//等价于i = k; k = k + 1;
int j = ++k;//等价于k = k + 1;j = k;
自减运算也可如此推理。
三、赋值运算符
赋值运算就是将某个运算后的值,赋给指定的变量。
赋值运算符 | 运算 |
= | 将右边的值赋给左边的变量 |
+= | a += b -> a = a + b; |
-= | a -= b -> a = a - b; |
*= | a *= b -> a = a * b; |
/= | a /= b -> a = a / b; |
%= | a %= b -> a = a % b; |
以+=为例:
int a = 10;
int k = 20;
k += a;
System.out.println(k);//30
赋值运算符的特点:
- 运算顺序从右向左,比如这条语句:int num = a + b,先计算a+b,再赋值给num。
- 赋值运算符的左边只能是变量,右边可以是变量、表达式、常量值。
- 复合赋值运算符会进行类型转换。看这个例子:
byte k = 1;
k += 1;
注意这条语句等价于 k = k + 1;右边的式子先运算并且由于类型提升为整型,与左边的类型不同。为了方便,这里编译器会帮我们进行强制的类型转换,所以这条语句等价于k = (byte)(k+1),另外++k,k++也是这样的。
四、关系运算符
关系运算符也叫比较运算符。
运算符 | 运算 | 范例 | 结果 |
== | 相等于 | 8==7 | false |
!= | 不等于 | 8!=7 | true |
< | 小于 | 8<7 | false |
> | 大于 | 8>7 | true |
<= | 小于等于 | 8<=7 | false |
>= | 大于等于 | 8>=7 | true |
instanceof | 检查是否是类的对象 | "Ca"instacnceof String | true |
五、逻辑运算符
逻辑运算符是用于在逻辑表达式中连接两个或多个逻辑量(如布尔值)的符号,它们用于构造复杂的条件语句。
a | b | a&&b | a&b | a||b | a|b | !a | a^b |
true | true | true | true | true | true | false | false |
true | false | false | false | true | true | false | true |
false | true | false | false | true | true | true | true |
false | false | false | false | false | false | true | false |
- a&b:&叫做逻辑与,当a和b同时为true,则结果为true,否则结果为false。
- a&&b:&&叫做短路与,当a和b同时为true,则结果为true,否则结果为false。
- a|b:|叫做逻辑或,当a和b至少有一个为true时,结果为true,否则为false。
- a||b:||叫做短路或,当a和b至少有一个为true时,结果为true,否则为false。‘
- !a:!叫做取反,也叫做非运算,当a为false时,结果为true,否则为false。
- a^b:^叫做逻辑异或,当a和b不同时,结果为true,否则结果为false。
&&与&的区别:
- &&短路与:如果第一个条件为false,则第二个条件不会判断,最终结果为false,效率高。
- &逻辑与:不管前面的条件是否为false,后面的条件都要判断,效率低。
int a = 10;
int b = 20;
if(a > 9 && b++ > 19) //第二个式子执行了
System.out.println("\n");
b = 20;
System.out.println(b);
if(a > 10 && b++ > 19) //第二个式子没执行。
System.out.println("\n");
System.out.println(b);
||与|的区别:
- ||短路或:如果第一个条件为true,则后续条件不会判断,最终结果为true,效率高。
- |逻辑或:所有判断条件必须全部执行完,效率低。
int a = 10;
int b = 20;
if(a > 9 | b++ > 19) //第二个式子执行了
System.out.println("\n");
System.out.println(b);
b = 20;
if(a > 9 || b++ > 19) //第二个式子没执行。
System.out.println("\n");
System.out.println(b);
六、位运算符
位运算是直接对整数类型的二进制位进行操作的运算。Java支持七种位运算。
位运算符 | 功能 |
按位与& | 两位为1,结果为1,否则为0 |
按位或| | 至少一位为1,结果为1,否则为0 |
按位异或^ | 两位不相同,结果为1,否则为0 |
按位取反~ | 0 -> 1,1 -> 0 |
算术右移>> | 低位溢出,符号位不变,符号位补高位 |
算术左移<< | 符号位不变,高位溢出,低位补0 |
逻辑右移>>> | 无符号右移,低位溢出,高位补0 |
按位与&:
int k = 2;
int m = 7;
int n = m & k;
System.out.println(n);//输出为2
//00000000 00000000 00000000 00000010 = 2
//00000000 00000000 00000000 00001011 = 7
//00000000 00000000 00000000 00000010 = 2
按位或|:
int k = 2;
int m = 7;
int n = m | k;
System.out.println(n);//输出为7
//00000000 00000000 00000000 00000010 = 2
//00000000 00000000 00000000 00001011 = 7
//00000000 00000000 00000000 00001011 = 7
按位异或^:
int k = 2;
int m = 7;
int n = m ^ k;
System.out.println(n);//输出为5
//00000000 00000000 00000000 00000010 = 2
//00000000 00000000 00000000 00001011 = 7
//00000000 00000000 00000000 00001001 = 5
按位取反~:
int n = -2;
System.out.println(~n);//输出为2
//10000000 00000000 00000000 00000010 -2的原码
//11111111 11111111 11111111 11111110 -2的补码
//00000000 00000000 00000000 00000001 取反后是个正数,正数的三码合一
算术右移>>:
int n = -2;
System.out.println(n >> 1); //输出为-1
//10000000 00000000 00000000 00000010 -2的源码
//11111111 11111111 11111111 11111110 -2的补码
//11111111 11111111 11111111 11111111 右移一位,最低为的0丢弃,最高位补上符号位
//10000000 00000000 00000000 00000001 变成原码 = -1
算术左移<<:
int n = -2;
System.out.println(n << 1);//输出为-4
//10000000 00000000 00000000 00000010 -2的原码
//11111111 11111111 11111111 11111110 -2的补码
//11111111 11111111 11111111 11111100 左移,高位舍弃,低位添0
//10000000 00000000 00000000 00000100 变回原码 = -4
逻辑右移>>>:
int n = -2;
System.out.println(n >>> 1); 输出为2147483646
//10000000 00000000 00000000 00000010 -2的原码
//11111111 11111111 11111111 11111110 -2的补码
//01111111 11111111 11111111 11111111 逻辑右移,不考虑符号位,但是还原为原码的时候要考虑 = 2147483646
逻辑右移要特别注意,只有在进行右移的时候才不考虑符号位,其它时候操作需要考虑,另外不存在逻辑左移。
七、三元运算符
三元运算符中的一个条件运算符,它允许你在一条语句中进行条件选择。它的一般形式为:
condition ? expression1 : expression2;
这里的condition是一个布尔表达式,它会被评估为true或false。如果condition的结果为true,则整个三元表达式的结果是expression1的值;如果condition的结果为false,则结果是expression2的值。举个例子,假设你要求三个数中的最大数,使用三元运算符应该怎么做?
方法一:使用两个三元运算符。
int a = 10;
int b = 20;
int c = 30;
int MaxNumber = a > b ? a : b;
MaxNumber = MaxNumber > c ? MaxNumber : c;
方法二:使用一个三元运算符:
int a = 10;
int b = 20;
int c = 30;
int MaxNumber = (a > b ? a : b) > c ? (a > b ? a : b) : c;
从代码可读性的角度来看,当然是方法一比较清晰。
三元运算符使用注意事项:
- expression1和espression2需要时可以赋给接受变量的类型(或者可以自动类型转换)。
- 三元运算符可以转化成if-else语句。