一、算术运算符
算术运算符为二元运算符,运算顺序从左往右,包括加减乘除和取模,知识点如下:
- 运算时如果两个数是不同类型,会先进行隐式类型转换或自动解包,再运算
- 取模运算符可以判断整数和奇偶,可以用在判断条件中
- 加减号除了作为加减法运算符,还可以作为正负号(一元运算符)
- 当任何值和字符串相加时,加号作为连接符,先将非字符串元素转换为字符串元素,然后进行字符串拼接
- 不用记各种运算优先级,使用小括号即可
如下例:
public class Test04 {
public static void main(String[] args) {
compute();
stringConcat();
}
private static void compute() {
int i = 8;
double d = 25.5;
System.out.println("加:" + (i + d) + "\n减:" + (i - d) + "\n乘:" + (i * d) + "\n除:" + (i / d) + "\n取模:" + (i % d));
Scanner s = new Scanner(System.in);
System.out.print("请输入任意整数:");
double b = s.nextDouble();
System.out.println((b % 1 != 0) ? "您输入的是小数" : (b % 2 == 0) ? "您输入的是偶数" : "您输入的是奇数");
s.close();
}
private static void stringConcat() {
System.out.println("5+5 = " + 5 + 5);//结果为5+5=55,过程是先拼接出"5+5=5",然后继续进行拼接
System.out.println("5+5 = " + (5 + 5));//结果为5+5=10,过程是先计算出10,再进行字符串拼接
System.out.println(5 + 5 + " = 5+5");//结果为10=5+5,这是因为+操作符的顺序是从左往右,先进行了加法运算,然后才进行字符串拼接
System.out.println("haha" + null);//结果为hahanull,这个小知识点要注意下
}
}
二、自增/减运算符
自增/减运算符为一元运算符,包括++和--(使用方法分为前缀式和后缀式),示例代码如下:
public class Test05 {
public static void main(String[] args){
int a = 1;
int b;
b=a++;//先将a的值赋给b,再将a的值加1
System.out.println("a="+a+",b="+b);//结果a=2,b=1
b=++a;//先将a的值加1,再将a的值赋给b
System.out.println("a="+a+",b="+b);//结果a=3,b=3
b=a--;//先将a的值赋给b,再将a的值减1
System.out.println("a="+a+",b="+b);//结果a=2,b=3
b=--a;//先将a的值减1,再将a的值赋给b
System.out.println("a="+a+",b="+b);//结果a=1,b=1
int i=1;
i=i++;
System.out.println(i);//结果为1
}
}
三、赋值运算符
赋值运算符是最常用的运算符,包括=,+=,-=,*=,/=,%=,a+=b等同于a=a+b(其他同理)。
示例代码如下:
public class Test06 {
public static void main(String[] args){
int i=5;
System.out.println("i+=1的值为:"+(i+=1));//6
System.out.println("i-=1的值为:"+(i-=1));//5
System.out.println("i*=2的值为:"+(i*=2));//10
System.out.println("i/=2的值为:"+(i/=2));//5
System.out.println("i%=2的值为:"+(i%=2));//1
byte b=1;
//!b=b+1;
b+=1;//+=运算符之所以可以,是在底层进行了自动强转
System.out.println(b);
}
}
面试要点1 之前说过上例中b=b+1无法通过编译,那b+=1为什么就可以通过编译呢?这是由于b+=1在底层直接进行了强转过程(与int类型的自动强转一样,实际上这存在弊端,可能造成溢出)。
面试要点2 诸如i=1;falg=true;是有返回值的,返回值即为等号右侧的值。
四、比较运算符
比较运算符为二元运算符,它比较简单(==和!=还可以比较引用,之后会详细讲解),直接看示例程序即可:
public class Test07 {
public static void main(String[] args){
int a=3;
float b=3.0f;
System.out.println(a>b);//false
System.out.println(a<b);//false
System.out.println(a>=b);//true
System.out.println(a<=b);//true
System.out.println(a==b);//true
System.out.println(a!=b);//false
}
}
五、逻辑运算符
逻辑运算符为二元运算符,运算顺序从左往右,包括逻辑与(&&,&)、逻辑或(||,|)、逻辑非(!)、逻辑异或(^),逻辑运算符的结果为布尔值,逻辑运算符的知识点如下:
- &&、&(逻辑与):两个都对才对
- ||、|(逻辑或):只要有一个对就对
- !(逻辑非):对就是错,错就是对
- ^(逻辑异或):相同就是错,相反就是对
- &、|和^也可以作为按位运算符
- &和|必须将两边都计算完成才能得出结果
- &&只要确定第一个false,就不会继续计算后面的布尔值,直接为false(短路)
- ||只要确定第一个true,就不会计算后面的布尔值,直接为true(短路)
- 建议使用&&和||作为逻辑与和逻辑或,这样可以获得潜在的性能提升
示例代码:
public class Test08 {
public static void main(String[] args){
System.out.println((3>2)&&(2>1));//true
System.out.println((2>3)&(2>1));//false
System.out.println((2>3)||(2>1));//true
System.out.println((2>3)||(1>2));//false
System.out.println((3>2)|(1>2));//true
System.out.println((2>3)^(2>3));//false
System.out.println((3>2)^(2>3));//true
System.out.println(!true);//false
}
}
六、位运算符
位运算符为二元运算符,运算顺序从左往右,包括按位与(
&
)、按位或(
|
)、按位非(~)、 按位异或(^)和移位运算符,位运算符的知识点如下:
- 位运算符包括按位运算符和移位运算符
- 按位运算符与逻辑运算符类似,不过按位运算符是操作二进制序列
- 按位与&:两个是1才是1
- 按位或|:有一个1就是1
- 按位非~:1是0,0是1
- 按位异或^:相同是0,相反是1(一个数异或同一个数两次还是这个数)
- 移位运算符只能处理整数类型
- 左移运算符<<是将操作符左侧的二进制序列左移操作符右侧的位数,然后在低位补0
- 右移操作符>>是将操作符左侧的二进制序列右移操作符右侧的位数,若原来数字的符号为正,在高位补0;若原来数字的符号为负,在高位补1
- 无符号右移操作符>>>是将操作符左侧的二进制序列右移操作符右侧的位数,无论原数字正负一律在高位补0
- 左移n位相当于把数乘以2的n次方(2*8最快的运算方法就是左移3位)
- 右移n位相当于把数除以2的n次方
- 正数无符号右移n位相当于把数除以2的n次方
- 负数无符号右移没有以上规律
示例代码:
public class Test09 {
public static void main(String[] args){
int a=6;
int b=3;
int c=8;
int d=-8;
System.out.println("按位与"+(a&b));//2
System.out.println("按位或"+(a|b));//7
System.out.println("按位非"+(~a));//-7
System.out.println("按位异或"+(a^b));//5
System.out.println("连续按位异或两次"+(a^b^b));//6
System.out.println("将8左移1位"+(c<<1));//16
System.out.println("将8右移1位"+(c>>1));//4
System.out.println("将8无符号右移1位"+(c>>>1));//4
System.out.println("将-8右移1位"+(d>>1));//-4
System.out.println("将-8无符号右移1位"+(d>>>1));//2147483644
//面试题:如何在不使用第三方变量的前提下交换两个数的值?
//第一种方法:
int m=3;
int n=5;
System.out.println("交换之前m="+m+",n="+n);
m=m+n;
n=m-n;
m=m-n;
System.out.println("交换之后m="+m+",n="+n);
//不过这种方式不建议使用,如果两个数过大,和会超出int范围,底层会自动进行强制转换,数据会变化
//第二种方法(原理:一个数异或同一个数两次还是这个数):
int x=3;
int y=5;
System.out.println("交换之前x="+x+",y="+y);
x=x^y;
y=x^y;
x=x^y;
System.out.println("交换之后x="+x+",y="+y);
//不过实际工作中还是要用第三方变量,提高代码可阅读性
int i1=3;
int i2=5;
int temp;
System.out.println("交换之前i1="+i1+",i2="+i2);
temp=i1;
i1=i2;
i2=temp;
System.out.println("交换之后i1="+i1+",i2="+i2);
}
}
面试要点 如何在不使用第三方变量的前提下交换两个数的值?代码中的第一种方法不建议使用,原因还是如果数值大于int的范围,底层进行自动强转,有可能造成溢出(老问题了)。第二种方法的原理就是一个数异或同一个数两次还是这个数,不过这玩意儿除了面试就别用了,代码可读性很差 还是踏实定义一个temp变量自己“换座位”比较好。
七、三元运算符
三元运算符实际就是if-else的另一种形式,格式为条件式?值1:值2或者条件式1?值1:条件式2?值2:值3,分别对应了if-else和if-else if-else,示例代码:
public class Test10 {
public static void main(String[] args){
Scanner s=new Scanner(System.in);
System.out.print("请输入一个数:");
Double d=s.nextDouble();
String str=(d%1!=0)?"这不是一个整数":(d%2==0)?"这是一个偶数":"这是一个奇数";
System.out.println(str);
s.close();
//练习:获取三个整数中最大的数
int a = 4;
int b = 2;
int c = 3;
int temp=(a>b)?a:b;
int max=(c>temp)?c:temp;
System.out.println("最大数是"+max);
}
}
到此,运算符学习完成,巩固了许多不熟悉的知识点,也学习了一些新内容 明儿个搞定流程控制!