计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量。我们可以把运算符分成以下几组:
- 算术运算符:+,-,*,/,%,++,–
- 赋值运算符:=,+=,-=,*=,/=
- 关系运算符:>,<,>=,<=,==,!= ,instanceof
- 逻辑运算符:&&,||,!
- 位运算符:&,|,^,~,>>,<<,>>>
- 条件运算符:(?:)
- 其他运算符
一、算术运算符:+,-,*,/,%,++,–
(1)+,-,*,/
int a = 10;
int b = 20;
System.out.println(a+b);
System.out.println(a-b);
System.out.println(a*b);
System.out.println(a/b);
得到的结果:30 ,-10 ,200 ,0
显然,a/b 的结果是错误的,正确结果应该是0.5 。这是因为a和b都是int型,得到的结果也是int型,小数部分被舍去了。
如何得到正确结果呢?需要进行强制转换,如下所示:
System.out.println(a/(double)b);
将 b 强制转换为浮点型,此时输出结果为 0.5 ,结果正确。
上面的例子中,操作数属于同种数据类型,接下来我们尝试使用不同的数据类型值进行运算,看看结果如何。
long a = 123123123123123123L;
int b = 123;
short c = 10;
byte d = 8;
System.out.println(a+b+c+d); //Long
System.out.println(b+c+d); //int
System.out.println(c+d); //int
得到的结果为123123123123123264 ,141 ,18
这三个结果分别为long、int、int 类型。
因为abcd四个数中,有一个为long类型,因此四个数相加也为long类型。
而 int,short,byte三种类型相加,或者其中任意两种相加,都会得到int类型。
可能有人会疑惑,c 和 d 分别是short和byte型, 为什么short和byte相加也会得到int类型?这是从哪里看出来的呢?我们可以对此进行验证。
如图所示,我们尝试着将(c+d)的结果转换为String型,可以看到,idea提示 “ 不能把int型转换为string ” 型。由此可知,(c+d)的结果为int类型。
我在 Java类型转换 这篇文章中曾经提到过这一点,即所谓的 “ 隐含强制类型转换 ”,整数的默认类型是 int 。
(2)%(模运算,即“取余”)
int a = 10;
int c = 21;
System.out.println(c%a);
得到的结果为1。即 21/10=2……1,模运算结果即为余数1。
(3)++,–(自增,自减)
++,-- 运算只需要一个操作数,因此为一元运算符。
int a = 3;
int b = a++;
int c = ++a;
System.out.println(a);
System.out.println(b);
System.out.println(c);
得到的结果:5,3,5 。
那么,a++ 与 ++a 有何不同呢?
- b = a++ 相当于: b=a; a=a+1; 即先赋值,再自增。
- c = ++a 相当于: a=a+1; c=a; 即先自增,再赋值。
(4)拓展:使用Math工具类进行运算
比如幂运算,如果要计算2^3,即2的三次方,在Java中应当如何操作呢?此时需要使用Math工具类中的pow来进行计算。
//幂运算 2^3 2*2*2=8
double pow = Math.pow(2,3);
System.out.println(pow);
得到的结果为 8.0 。
二、赋值运算符:=,+=,-=,*=,/=
a+=b; // a=a+b
a-=b; // a=a-b
a*=b; // a=a*b
a/=b; // a=a/b
三、关系运算符:>,<,>=,<=,==,!= ,instanceof
关系运算符的返回结果有两种:true,false
int a = 10;
int b = 20;
System.out.println(a>b);
System.out.println(a<b);
System.out.println(a==b);
System.out.println(a!=b);
输出结果为false,true,false,true
四、逻辑运算符:&&,||,!
&&,||,! 运算符分别为 “与”(and),“或”(or), “非” (取反)
boolean a =true;
boolean b =false;
System.out.println("a && b:"+ (a&&b)); //逻辑与运算
System.out.println("a || b:"+ (a||b)); //逻辑或运算
System.out.println("!(a && b):"+(!(a && b))); //逻辑非运算
输出结果如下所示:
此处我们介绍一个概念:短路逻辑运算符
拿 b&&a
举例,如果 b 为假,则根本不会执行后面的a,便会直接输出结果false。即执行完b之后就 “短路” 了。
接下来,我们将对这一点进行验证,代码如下所示:
int c = 5;
boolean d = (c<4)&&(c++>1);
System.out.println(d);
System.out.println(c);
输出结果为 false,5。
该程序使用到了短路逻辑运算符(&&), 在判断 c<4 为假后,系统便直接跳到了下一步的输出操作,并没有执行c++这一步。
五、位运算符:&,|,^,~,>>,<<,>>>
(1) &(与),|(或),^(异或),~ (非)
A&B: 两个都为1时,结果才为1。
A| B: 两个都为0时,结果才为0。
A ^B: 两数相同则为0。
~ B: 与B完全相反。
举例:
A = 0011 1100
B = 0000 1101
A&B: 0000 1100
A| B: 0011 1101
A ^B: 0011 0001
~ B: 1111 0010
(2)<<(左移),>>(右移)
计算机中的机器码其实是二进制数,而二进制数与十进制数的对应关系如下所示:
0000 0000 0
0000 0010 2
0000 0100 4
0000 1000 8
0001 0000 16
我们可以看到,二进制中的 “1” 每左移一位,它所对应的十进制数的值就乘以2。同理,每右移一位,值则除以2。
System.out.println(2<<3);
上面这行代码的输出结果为16。即左移三位后,对应十进制数的值为16。
由于位运算直接涉及底层,因此效率极高。
六、条件运算符:(?:)
这是一种三元运算符,我们令三个操作数分别为x,y,z。
此时,x ? y : z
意为: 如果x==true,则结果为 y,否则结果为z。
如下所示,如果 分数 < 60,则输出 “不及格” ,否则输出 “及格” 。
int score = 80;
String type = score <60 ?"不及格":"及格";
System.out.println(type);
输出结果为 “及格” 。
七、字符串连接符: +
首先定义两个int类型变量:
int a = 10;
int b = 20;
输出a+b:
System.out.println(a+b);
结果为30。
接下来,输出 “”+a+b
System.out.println(""+a+b);
输出结果为1020。
这是由于在连接符 ‘ + ’ 两侧,一方是String类型,执行到String类型处时,它会把加号另一侧也转换成String类型,再进行拼接。
此时,我们再将String类型的字符串移动到加号最右侧,看看是否会得到同样的结果。
System.out.println(a+b+"");
输出结果为30。
这是因为代码按照从左到右的顺序执行,a+b执行后,结果已经是30了,此时再执行到String处,变成String类型,也仍然是30。