文章目录
前言
Java中运算符可分为以下:算术运算符(+ - * /),关系运算符(< > ==),逻辑运算符,位运算符,移位运算符以及条件运算符等。
一、算术运算符
1.基本四则运算符
public class identifier {
public static void main(String[] args){
int a=20;
int b=10;
System.out.println(a+b);
System.out.println(a-b);
System.out.println(a*b);
System.out.println(a/b);
System.out.println(a%b);//模运算:除后取余
}
}
注意:做除法和取模时,右操作数不能为0。
public static void main(String[] args){
int a=1;
int b=0;
System.out.println(a/b);
}
另外,%不仅可以对整形取模,也可以对double类型取模,但是对double没有任何意义,一般都是针对整形。
public static void main(String[] args) {
System.out.println(1+0.2);
}
当两侧操作数类型不一致时,类型小的向类型大的提升,比如上例1是int型,0.2是double类型,int提升为double,1提升为1.0,结果为1.2。
2.增量运算符
+=、-=、=、%=。该种类型运算符操作完成后,会将操纵的结果赋值给左操作数。
例如:
a+=2 -->a=a+2
a-=1 -->a=a-1
a ** =3 -->a=a3
a/=3 -->a=a/3
a%=3 -->a=a%3
注意:只有变量才能使用该运算符,常量不能使用。
3.自增/自减运算符
通过代码给大家演示一下它的功能
代码如下(示例):
public static void main(String[] args){
int a=1;
a++;//后置++,表示给a的值+1,此时a的值为2
System.out.println(a++);//注意:后置++是先使用变量原来值,表示式结束时给变量+1,因此输出2
System.out.println(a);//3
++a;//前置++,表示给a的值+1,此时a的结果为4
System.out.println(++a);//注意:前置++是先给变量+1,然后使用变量中的值,因此输出5
System.out.println(a);//输出5
注意:
1.如果单独使用,前置++和后置++没有任何区别。
2.如果混合使用,前置++先+1,然后使用变量+1后的值,后置++先使用变量原来的值,表达式结束时给变量 +1。
3.只有变量才能使用自增/自减运算符,常量不能使用,因为常量不允许被修改。
二、关系运算符
关系运算符主要有6个:==、!=、<、>、<=、>=。其运算结果是true或者false。
代码如下(示例):
public static void main(String[] args){
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);
System.out.println(a<=b);
System.out.println(a>=b);
}
注意这里与数学符号的区别,Java中=表示赋值,==是比较相等。
当需要多次判断时,不能连着写,比如:3<a<5。
三、逻辑运算符(重点)
逻辑运算符主要有三个:&&、||、!,运算结果都是boolean类型。
1.逻辑与&&
语法规则:表达式1&&表达式2,左右表达式必须是boolean类型的结果。相当于现实生活中的且,两个表达式都为真,结果才为真,只要有一个为假,结果就是假。
public static void main(String[] args){
int a=1;
int b=2;
System.out.println(a==1&&b==2);//左为真右为真则结果为真
System.out.println(a==1&&b>100);//左为真右为假则结果为假
System.out.println(a>100&&b==2);//左为假右为真则结果为假
System.out.println(a>100&&b>100);//左为假右为假则结果为假
}
2.逻辑或||
语法规则:表达式1||表达式2,左右表达式必须是boolean类型的结果,相当于现实中的或,只要一个为真,则结果为真。
public static void main(String[] args){
int a=1;
int b=2;
System.out.println(a==1||b==2);//左为真右为真则结果为真
System.out.println(a==1||b>100);//左为真右为假则结果为真
System.out.println(a>100||b==2);//左为假右为真则结果为真
System.out.println(a>100||b>100);//左为假右为假则结果为假
}
3.逻辑非!
语法规则:!表达式
真变假,假变真。
public static void main(String[] args){
int a=1;
System.out.println(!(a==1));//a==1是true,取个非就是false
System.out.println(!(a!=1));//a!=1为false,取个非就是true
}
4.短路求值
&&和||遵守短路求值的规则。
public static void main(String[] args){
System.out.println(10>20&&10/0==0);
System.out.println(10<20||10/0==0);
}
运行结果:
都知道,计算10/0会导致程序抛出异常,但是上述的代码却能正常运行,说明10/0并没有真正被求值。
注意:
1.对于&&,如果左侧表达式值为false,则表达式结果一定是false,无需计算右侧表达式。
2.对于||,如果左侧表达式值为true,则表达式结果一定是true,无需计算右侧表达式。
3.&和|如果表达式结果为boolean时,也表示逻辑运算,但与&&和||相比,他们不支持短路求值。
public static void main(String[] args){
System.out.println(10>20&10/0==0);
System.out.println(10<20|10/0==0);
}
程序抛出如下异常:
四、位运算符
Java中数据存储的最小单位是字节,而数据操作的最小单位是比特位,字节是最小的存储单位,每个字节是由8个二进制比特位组成的,多个字节组合在一起可以表示各种不同的数据。
位运算符主要有四个:& | ~ ^,除~是一元运算符外,其余都是二元运算符。
位操作表示按二进制位运算,计算机中都是使用二进制来表示数据的,按位运算就是在按照二进制位的每一位依次进行运算。
1.按位与&:
如果两个二进制位都是1,则结果为1,否则结果为0.
public static void main(String[] args){
int a=10;
int b=20;
System.out.println(a&b);
}
运算结果:
示意图:
2.按位或 |:
如果两个二进制位都是0,则结果为0,否则结果为1.
public static void main(String[] args){
int a=10;
int b=20;
System.out.println(a|b);
}
运算结果:
示意图:
注意:当&和 | 的操作数为整数(int,short,long,byte)的时候,表示按位运算,当操作数为boolean的时候,表示逻辑运算。
3.按位取反~:
如果该位为0,则转为1,如果该位为1,则转为0.
public static void main(String[] args){
int a=0xf;
System.out.printf("%x\n",~a);
}
运算结果:
示意图:
注意:
①0x前缀的数字为十六进制数字,十六进制数字可以看成是二进制的简化表示形式,一个十六进制对应4个二进制位。
②0xf表示10进制的15,也就是二进制的1111.
③printf能够格式化输出内容,%x表示按照十六进制输出。
4.按位异或^:
如果两个数字的二进制位相同,则结果为0,相异则结果为1.
public static void main(String[] args){
int a=0x1;
int b=0x2;
System.out.printf("%x\n",a^b);
}
运算结果:
示意图:
注意:如果两个数相同,则异或的结果为0.
五、移位运算(了解)
移位运算符有三个:<< >> >>>,都是二元运算符,且都是按照二进制比特位来运算的。
1.左移<<:
最左侧位不要了,最右侧补0.
public static void main(String[] args){
int a=0x10;
System.out.printf("%x\n",a<<1);
}
运行结果:
示意图:
2.右移>>:
最右侧位不要了,最左侧补符号位(正数补0,负数补1)
public static void main(String[] args){
int a=0x10;
System.out.printf("%x\n",a>>1);
int b=0xffff0000;
System.out.printf("%x\n",b>>1);
}
运行结果:
示意图:
3.无符号右移>>>:
最右侧位不要了,最左侧补0.
public static void main(String[] args){
int a=0xffffffff;
System.out.printf("%x\n",a>>>1);
}
运行结果:
示意图:
注意:
1.左移1位,相当于原数字乘二,左移n位,相当于原数字乘二的n次方。
2.右移1位,相当于原数字除以二,右移n位,相当于原数字除以二的n次方。
3.由于计算机计算移位效率高于计算乘除,当某个代码正好乘除2的n次方的时候可以用移位运算代替。
4.移位负数位或者移位位数过大都没有意义。
六、条件运算符
条件运算符只有一个:表达式1 ? 表达式2 :表达式3;
当表达式1的值为true时,整个表达式的值为表达式2的值;
当表达式1的值为false时,整个表达式的值为表达式3的值。
是Java中唯一的一个三目运算符,是条件判断语句的简化写法。
public static void main(String[] args){
//求两个整数的最大值
int a=10;
int b=20;
int max=a>b?a:b;
}
注意:1.表达式2和表达式3的结果要是同类型的,除非能发生隐式类型转换。
public static void main(String[] args){
//求两个整数的最大值
int a=10;
int b=20;
int c=a>b?1:2.0;
}
以上程序应执行表达式3的值,将2.0赋值给c,但是c为int类型,double赋值给int可能会有损失,所以程序报错。
2.表达式不能单独存在,其产生的结果必须要被使用,返回值必须要被接收,否则编译失败。
public static void main(String[] args){
//求两个整数的最大值
int a=10;
int b=20;
a>b?a:b;
}
七、运算符的优先级
在一条表达式中,各个运算符可以混合起来进行运算,但是运算符的优先级不同,比如:*和/的优先级要高于+和-,有些情况下稍不注意,可能会造成很大的麻烦。
通常我们求两个数的平均值会用(a+b)/2,这种方式其实不太好,原因是:
1.如果a和b的值非常大,加完之后可能会溢出。
2.除法运算效率非常低。
可以采用如下图所示的这种方法:
用公式表示为:a+(b-a)>>1注意:这里不能用无符号右移,因为不能保证b-a的结果是正数还是负数。
程序如下:
public static void main(String[] args){
int a=10;
int b=20;
int ret=a+(b-a)>>1;
System.out.println(ret);
}
结果本应该是15,却发现运行结果为10,这是为什么呢?
主要是运算符优先级的问题,+号的优先级要比>>的优先级高,所以这里会先算a+(b-a),结果为20,之后>>1,结果为10。这里解决办法很简单,只需要把(b-a)>>1加上括号即可。
当程序中有优先级不确定的时候,最好的解决办法就是加上括号。