Day03
一、算数运算符的使用
符号:+、-、*、/、%、++、--
++:自增1
++a:先自增1,再使用
a++:先使用,在自增1
--:同理
二、算数运算符的深入--特殊点
特殊点1
byte做运算会先向上转型成int类型,再做运算
byte b1 = 10; byte b2 = 20; //底层实现 //b1 - byte:0000,1010 // int:0000,0000,0000,0000,0000,0000,0000,1010 //b2 - byte:0001,0100 // int:0000,0000,0000,0000,0000,0000,0001,0100 //结果 -int:0000,0000,0000,0000,0000,0000,0001,1110 // (byte):0001,1110 byte result = (byte)(b1 + b2); System.out.println(result);t
特殊点2
short做运算会向上转型成int类型,再做运算
short s1 = 10; short s2 = 20; //底层实现 //s1 - short:0000,0000,0000,1010 // int:0000,0000,0000,0000,0000,0000,0000,1010 //s2 - short:0000,0000,0001,0100 // int:0000,0000,0000,0000,0000,0000,0001,0100 //结果 - int:0000,0000,0000,0000,0000,0000,0001,1110 // (short):0000,0000,0001,1110 short result = (short)(s1 + s2); System.out.println(result);
特殊点3
byte和short做运算会向上转型成int,其余数值型按照取值范围大的类型转型后在做运算
byte b = 10; short s = 10; int i = 10; long l = 10; float f = 10; double d = 10; System.out.println(b + b);//运算结果是int类型 System.out.println(s + s);//运算结果是int类型 System.out.println(b + s);//运算结果是int类型 System.out.println(b + i);//运算结果是int类型 System.out.println(b + l);//运算结果是long类型 System.out.println(i + l);//运算结果是long类型 System.out.println(i + f);//运算结果是float类型 System.out.println(l + f);//运算结果是float类型 System.out.println(l + d);//运算结果是double类型 System.out.println(f + d);//运算结果是double类型
特殊点4
char类型可以做运算,获取到的是字符的Unicode码值
char c = 'a';//Unicode - 97 int i = c+1; System.out.println(i);//98
特殊点5
浮点类型做运算时可能会损失精度,如果考虑精度问题可以使用BigInteger或BigDecimal类去解决问题
float f1 = 0.5f; float f2 = 0.4f; System.out.println(f1-f2); // 0.099999994
特殊点6
++a;和 b++;没有区别,因为分号是执行语句的结束符,不管是先加还是后加都给我自增了
特殊点7:
byte num = 10; ++num; // 底层原理: num = (byte)(num+1); System.out.println(num); // 11
三、算数运算符的深入 --经典面试题
经典面试题一
int a = 8; int b = (a++)+(++a)+(a*10); //计算会从左往右执行 // a = 10 // b = 8 + 10 + 100 System.out.println(b);//118
经典面试题二
int i = 0; i = ++i; //先自增1,再将自增后的值赋给i //底层实现: //i = (int)(i + 1); //i = i; System.out.println(i);//1
经典面试题三
int i = 0; i = i++; //先用临时变量接收i的初始值0,i再自增1,将自增后的值赋给左边的i,最后将临时变量的值赋给左 边的i,所以i为0 //底层实现: //int temp = i;//temp作为临时变量,记录了i最初的值 -- 0 //i = (int)(i+1);//i自增了 //i = temp;//又把0赋值给i System.out.println(i);//0
四、赋值运算符的使用及深入
经典面试题一
下面两种写法的结果是:
short s = 1; s = s+1; //会报错,short和int类型做运算,结果是int类型(大转小(强制类型转 换),不加(byte)会报错) short b = 1; b += 1; //底层:b = (short)(b + 1)
注意:= 赋值号,将赋值号右边的结果赋值给左边的变量
五、关系运算符的使用及深入
符号:==、!=、>、>=、<、<=
经典面试题一
int x = 10; int y = 10; boolean flag = (x == y); System.out.println(flag); //true flag = (x = y); //会报错,因为boolean值不能与其他类型兼容 System.out.printlnf(flag);
经典面试题二
boolean b1 = true; boolean b2 = false; boolean b3 = (b1 == b2); System.out.println(b3);//false boolean b4 = (b1 = b2); // = 为赋值符 System.out.println(b4);//false
注意:
1.关系运算符得结果必须是boolean类型
2.=是赋值号,==是判断两个值是否相同
3.!=是判断两个值是否不相同
4.!是英文符号
六、字符串拼接符的使用
符号:+
注意:
两侧都是数值的情况下,此符号为算数运算符
一侧或两侧都是字符串的情况下,此符号为字符串拼接符
七、Scanner类
Scanner类的使用步骤
1.导包 - import java.util.Scanner;
2.创建对象 - Scanner scan = new Scanner(System.in);
3.根据需求输入整数、小数、字符串
八、逻辑运算符的使用及深入
符号:
&与 &&短路与
|或 ||短路或
^异或
! 非
& vs &&: &与:判断前者为false后,还会判断后者 &&短路与:判断前者为flase后,不会判断后者,效率更高
| vs ||: |或:判断前者为true后,还会判断后者 ||短路或:判断前者为true后,不会判断后者,效率更高
九、三目运算符/三元运算符的使用
语法结构: 变量 = (表达式)?值1:值2; 理解: 表达式的结果必须是boolean类型 true - 将值1赋值给变量 false- 将值2赋值给变量
十、三目运算符/三元运算符的深入
扩展面试题1
int a = 5; System.out.println((a<5)?10.9:9); //输出结果:9.0
扩展面试题2
char x = 'x'; //Unicode - 120 int i = 10; System.out.println(false?i:x); //输出结果:120
扩展面试题3
char x = 'x' //Unicode - 120 System.out.println(false?100:x); //x System.out.println(false?100000:x) //120
核心思想:
1.若三目运算符中的两个表达式有一个是常量表达式,另一个是类型T的表达式,且常量表达式可以被T表示,则输出结果是T类型。
2.如果都是常量表达式,用向上类型转换
返回值原则
-
值1和值2都是常量的情况下,按照取值范围大的类型返回数据
-
值1和值2都是变量的情况下,按照取值范围大的类型返回数据
-
值1和值2一个是常量一个是变量的情况下,判断常量是否在变量所属类型的取值范围中 -- 在:按照变量类型返回数据 -- 不在:按照常量类型返回数据
十一、位运算符
将十进制的数据转成二进制做运算
符号:
&与 |或 ^异或
<< 左移 >> 右移 >>> 无符号右移
注意: &、|、^前后两侧都是数值,此符号为位运算符 &、|、^前后两侧都是布尔值,此符号为逻辑运算符
//<<左移:整体向左移动n位,就用n个0补位(补到最低位) //经验:左移1位相等于乘以2 int a = 1024;//0000,0000,0000,0000,0000,0100,0000,0000 System.out.println(a << 2);//4096 -- 0000,0000,0000,0000,0001,0000,0000,0000
左移会出现负数,当移动后的二进制数的首位(符号位)变为1
int b = 1024;//0000,0000,0000,0000,0000,0100,0000,0000 System.out.println(b << 21);
>> 右移:整体向右移动n位,就用n个最高位(符号位)补位(补到最高位,负数用1补位,正数用0补位) 注意:右移1位相等于除以2
int c = 1024;//0000,0000,0000,0000,0000,0100,0000,0000 左边用0补齐 System.out.println(c >> 2);//256 -- 0000,0000,0000,0000,0000,0001,0000,0000 int d = -1024;//1111,1111,1111,1111,1111,1100,0000,0000 左边用1补齐 System.out.println(d >> 2);//-256 -- 1111,1111,1111,1111,1111,1111,0000,0000
>>> 无符号位右移:整体向右移动n位,就用n个0补位(补到最高位)
int e = 1024;//0000,0000,0000,0000,0000,0100,0000,0000 System.out.println(e >>> 2);//256 -- 0000,0000,0000,0000,0000,0001,0000,0000 int f = -1024;//1111,1111,1111,1111,1111,1100,0000,0000 System.out.println(f >>> 2);//1073741568 -- 0011,1111,1111,1111,1111,1111,0000,0000
注意:右移和无符号位右移在处理正数的情况下都是一样的,因为正数用0补位
面试题1
使用最有效率的方式计算4*8
System.out.println(4<<3); // 0000,0000,0000,0000,0000,0000,0000,0100 -> 左移三位 0000,0000,0000,0000,0000,0000,0010,0000
面试题2
描述下列代码运行结果
考点:char类型向上转型使用0补位
//-1 -- int:1111,1111,1111,1111,1111,1111,1111,1111 // (byte):1111,1111 // (char):1111,1111,1111,1111 char类型向上转型用0补位 // (int):0000,0000,0000,0000,1111,1111,1111,1111 System.out.println((int)(char)(byte)-1);//65535