学习笔记之JavaSE(3)--Java基础语法2

时间:2023-02-16 07:44:25

一、算术运算符

算术运算符为二元运算符,运算顺序从左往右,包括加减乘除和取模,知识点如下:

  • 运算时如果两个数是不同类型,会先进行隐式类型转换或自动解包,再运算
  • 取模运算符可以判断整数和奇偶,可以用在判断条件中
  • 加减号除了作为加减法运算符,还可以作为正负号(一元运算符)
  • 当任何值和字符串相加时,加号作为连接符,先将非字符串元素转换为字符串元素,然后进行字符串拼接
  • 不用记各种运算优先级,使用小括号即可

如下例:

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
}
}


面试要点  b=a++的实际运算过程(b=a--同理):首先内存会划出一块临时存储区域,拷贝a的值并进行存储(假设这个是temp),然后再划出一块临时计算区域计算a+1的值,然后将计算结果赋给a,最后将临时存储区域存放的temp赋给b,所以在这里a=2,b=1。同理再看i=i++,内存会划出一块临时存储区域,拷贝i的值并进行存储(假设这个是temp),然后再划出一块临时计算区域计算i+1的值,然后将计算结果赋给i,最后将临时存储区域存放的temp赋给i,所以最后i的值就是temp的值,也就是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);
}
}


到此,运算符学习完成,巩固了许多不熟悉的知识点,也学习了一些新内容  明儿个搞定流程控制!