运算法是一种特殊的符号,用于表示数据的运算、复制、比较等。
1、算数运算符
// % 取余运算:结果的符号和被模数的符号一致
12 % 5 == 2
-12 % 5 == -2
12 % -5 == 2
-12 % -5 == -2
int a1 = 10;
int b1 = ++a1; // a1=11, b1=11
int a2 = 10;
int b2 = a2++; // a2=11, b2=10
short s1 = 10;
s1++; // 自增1,不会改变原本的数据类型
System.out.println(s1); // 11
byte b1 = 127;
b1++;
System.out.println(b1); // -128
负数补码变回原码:
方法1:减去1,符号位为1,其余位全部取反
方法2:由最低位(右)向高位(左)查找到第一个1与符号位之间的所有数字,按位取反
127 补码=原码:01111111, 127 + 1: 10000000
方法1:减1得 01111111,符号位为1其余为取反得 10000000
方法2: 第一个1已经是最后一个,因此没有数字需要取反,得到 10000000
在源码里面00000000和100000000都是表示0,这样比较浪费, 所以在补码里面,就把100000000当做 -2^7 ,以扩大补码表示范围
2、赋值运算符
赋值运算符:= (支持连续赋值)
扩展赋值运算符:+= -= *= /= %/
int j1, j2;
j1 = j2 = 3;
short s1 = 10;
s1 += 2; // 自增2,不会改变原本的数据类型
System.out.println(s1); // 12
int i1 = 1
i1 = i1 + 1; // 不推荐
i1 += i1; //推荐
i1++; //最推荐
int i1 = 2;
i1 *= 0.1; //不改变类型, 所以值为int型:0
System.out.println(i1); // 0
i1++;
System.out.println(i1); // 1
int n1 = 10;
n1 += (n1++) + (++n1); // n1 = n1 + (n1++) + (++n1)
System.out.println(n1); // 10+10+12=32
3、比较运算符
4、逻辑运算符
异或:不一样就是 true
& 与 && 运算结果相同,当左边为 false 时,& 继续执行右边的运算,&& 则不再继续运算。(其实就是 && 更聪明一些,不做无用功, 开发推荐 &&)
| 与 || 运算结果相同,当左边为 true 时,| 继续执行右边的运算,|| 则不再继续运算。
boolean x = true;
boolean y = false;
short z = 42;
if ((z++ == 42) && (y = true)) z++;
if ((x = false) || (++z == 45)) z++; // x=false 表示给x赋值false,所以判断为false
System.out.println(z); // 46
5、位运算符
位运算符是直接对整数的二进制进行的运算。
对于 & 、|、^,当运算的是数值,则是位运算符;当运算的是boolean类型,则是逻辑运算符。
// 两数交换数值
// method1:需要定义临时变量
int temp = num1;
num1 = num2;
num2 = temp;
// method2:好处就是不需要定义临时变量;坏处是:相加可能超出存储范围,只能用于数值型。
num1 = num1 + num2;
num2 = num1 - num2;
num1 = num1 - num2;
// method3:好处是不会超出存储范围,局限性是:只能用于数值型
num1 = num1 ^ num2;
num2 = num1 ^ num2; // (num1 ^ num2) ^ num2 -> num1, num1 赋值给 num2
num1 = num1 ^ num2; // (num1 ^ num2) ^ 原来num1的值 -> num2, num2 赋值给 num1
6、三元运算符
凡是 三元运算符 和 switch-case 的结构都可以改写为 if-else,反之不成立。三元运算符 和 switch-case 执行效率稍高于 if-else,所以如果取值较少时可选用 switch 或者 三元运算符。
int max = (m > n): m ? n; // 注意:两个可能结果需要一个统一的类型去接收
7、运算符的优先级
不建议死记硬背,在实际的应用中去体会,自然而然就会用了。