晨写
1、描述Java中的隐式转换和显示转换
1)隐式转换:默认类型提升
byte\short\char三者之间不参与转换,一旦参与到运算中,
优先转换为int,long, float,double
2)显示转换:强转类型转换
应用场景:
将大的数据类型转换成小的数据类型
目标数据类型 变量名=(目标数据类型)(结果);
2、byte类型的取值范围,若超出范围如何不报错?
-128-127
超出范围,Jvm会认为是int默认类型,需要进行强制转换
计算当前数据二进制(原—反—补),使用补码进行截取—》反码—〉原码
3、扩展的算术运算符++或—参与运算,在数据前/后的区别
==或—在数据前,先自增或自减,再参与运算
==或—在数据后,先参与运算,再自增或自减
4、扩展的赋值运算符的特点
+=,-=,*=,/=,%=
题:
Short s = 1;
1)s = s +1
2)s +=1
s +=1 ;// 扩展的赋值运算符:特点 隐藏了强制类型转换
// 等价于:s = (short)(s+1) ;
5、Java中的数据类型划分
基本数据/引用数据
基本数据(四大八类)
整数数据:
Byte
短整short
长整long
默认int
浮点:float/double
布尔:boolean
字符:char
引用数据:数组/类/接口
回顾内容重点
1.掌握(隐式转换和显示转换)
2.byte类型的取值范围
3.字符串拼接符号+,字符串+任何数据="新的字符串"
4.++和--参与运算的使用以及扩展的赋值运算符
今日内容
1.逻辑运算符(重点)
/*
逻辑运算符(运算符中相当重要的一个符号)
应用场景:在实际开发中,对业务层代码中需要对相关的业务需求进行逻辑判断
比如:用户要注册/登录
注册---需要在数据库中找是否存在这个用户
登录:用户名和密码必须一致,如果不一致,不能登录;
基本的逻辑运算符
逻辑单与&(并列关系)
特点: 有false,则false(你想,条件都要满足才行,有一个不满足就不行)
逻辑单或|(或的关系,交集)
特点:有true则true
逻辑异或^
特点:相同则为false,不同则为true
简单记忆:男女关系问题
男男:false
女女:false
男女:true
女男:true
逻辑非!
特点:非true,则false
偶数个非是它本身!
*/
class OperatorDemo{
public static void main(String[] args){
//定义三个变量
int a = 3 ;
int b = 4 ;
int c = 5 ;
//逻辑单与&(并列关系),条件必须同时满足才成立
System.out.println.((a>b)&(a>c)) ;//false & false = false
System.out.println.((a>b)&(a<c)) ;//false & true = false
System.out.println.((a<b)&(a>c)) ;//true & false = false
System.out.println.((a<b)&(a<c)) ;//true & true = true
//逻辑单或|(或的关系):满足一个条件即可成立
System.out.println.((a>b)|(a>c)) ;//false | false = false
System.out.println.((a>b)|(a<c)) ;//false | true = true
System.out.println.((a<b)|(a>c)) ;//true | false = true
System.out.println.((a<b)|(a<c)) ;//true | true = true
//逻辑异或^:相同则为false,不同则为true
System.out.println.((a>b)^(a>c)) ;//false ^ false = false
System.out.println.((a>b)^(a<c)) ;//false ^ true = true
System.out.println.((a<b)^(a>c)) ;//true ^ false = true
System.out.println.((a<b)^(a<c)) ;//true ^ true = false
//逻辑非!
System.out.println(!(a>b)) ;//!false = true
System.out.println(!!(a>b)) ;
System.out.println(!!!(a>b)) ;
//实际应用场景(用户登录时的逻辑判断)
/*前端,用户输入password,username,属于字符串
将数据发送给服务器(后端),进行接受参数和数据库中的信息进行匹配(逻辑判断)
String类型:(特殊的引用数据类型)
字符串比较,使用String的方法:equals(String other)
实际开发中,使用双与&&
if(!username.equals(数据库的name)&&!password.equals(数据库中的password))
如果都不一致,则登录失败
*/
}
}
/*
重点:逻辑双与&&逻辑双或||特点
面试题
逻辑双与&&和逻辑单与&有什么区别?
共同点:
都是表示并列关系,有false,则false
不同点:
具有"短路"效果
逻辑双与&& 连接的表达式:左边是false,右边就不执行了
好处: 提高逻辑判断的执行效率,开发中经常使用时逻辑双与&&和逻辑双或||
逻辑双或||和逻辑单|的区别
基本的特点:有true则true,表示或的关系
不同点:
逻辑双或||连接的左边表达式如果是true,右边就不执行了,具有短路效果!
好处: 提高逻辑判断的执行效率,开发中经常使用时逻辑双与&&和逻辑双或||
节省局部变量(在方法中运行的变量都是局部变量)(变量是有一个临时存储区域,栈内存)
在内存中访问次数,内存空间,提高开发效率
*/
class OperatorDemo2{
public static void main(String[] args){
//定义三个变量
int a = 3 ;
int b = 4 ;
int c = 5 ;
//逻辑双与&& 它基本的特点和逻辑单与&相同
System.out.println((a>b)&&(a>c)) ; //false && false =false
System.out.println((a>b)&&(a<c)) ; //false && true =false
System.out.println((a<b)&&(a>c)) ; //true && false =false
System.out.println((a<b)&&(a<c)) ; //true && true =true
//定义两个变量
int x = 3 ;
int y = 4 ;
System.out.println("x:"+x+",y:"+y) ;
System.out.println("---------------------") ;
//逻辑单与&
//System.out.println(((++x)==3) & ((y--)==4));//false
//( (++x)==3 )----->false x----->4 (++x)---->4
//( (y--)==4 )----->true (y--)----->4 y---->3
//false & true // false
//System.out.println("x:"+x+",y:"+y) ;
//x:4,y:3
//逻辑双与 &&
System.out.println(((++x)==3) && ((y--)==4));//false
System.out.println("x:"+x+",y:"+y) ;
//( (++x)==3 )----->false x----->4 触发短路,右边((y--)==4))就不运行了
//所以y还是4
//x:4,y:4
}
}
2.位运算符(了解即可--翻阅jdk原码时能看懂<<,>>,>>>)
/*
位运算符:对当前这些数据进行计算的(补码进行计算的)
基本位运算符:
位与&:有0则0
位或|:有1则1
位异或^:相同则为0,不同则为1
有另一个特点(见面试题):
(必须记住):一个数据被另一个数据如果位异或两次,其值是它本身!
~反码:全部按位取反(0变1,1变0)
其他的位运算符:移位符号
*/
class OperatorDemo{
public static void main(String[] args){
//位与&
System.out.println(3 & 4) ;// 0
//位或|
System.out.println(3 | 4) ;// 7
//位异或^
System.out.println(3 ^ 4) ;// 7
//反码~
System.out.println(~3) ;// -4
}
}
/*
1)位与&:(有0则0)
3 & 4---->计算出3和4对应的二进制原码(原码-->反码--->补码),使用补码进行计算
00000000 00000000 00000000 00000011 (原码反码补码相同)
00000000 00000000 00000000 00000100 (原码反码补码相同)
--------------------------------------------------------------- (有0则0)
00000000 00000000 00000000 00000000 补码反码原码相同
结果:0
2)位或&:(有1则1)
3 | 4
00000000 00000000 00000000 00000011 (原码反码补码相同)
00000000 00000000 00000000 00000100 (原码反码补码相同)
--------------------------------------------------------------- (有1则1)
00000000 00000000 00000000 00000111 补码反码原码相同
结果:7
3)位异或^ :(相同则为0,不同则为1)
3 ^ 4
00000000 00000000 00000000 00000011 (原码反码补码相同)
00000000 00000000 00000000 00000100 (原码反码补码相同)
--------------------------------------------------------------- (有1则1)
00000000 00000000 00000000 00000111 补码反码原码相同
结果:7
4)反码~:此时将这个数据全部按位取反,不分最高符号位,全部变
~3
3的原码
00000000 00000000 00000000 00000011
用补码进行:~(反码操作)全部按位取反,包括符号位
11111111 11111111 11111111 11111100
再用补码推原码:
最高符号位 数值位
1 1111111 11111111 11111111 11111100 补码(补码求反码,符号位不变,数值位-1)
- 1
----------------------------------------------------------------------
1 1111111 11111111 11111111 11111011 反码 (反码求原码,符号位不变,按位取反)
1 0000000 00000000 00000000 00000100 原码
- 4
结果:-4
*/
/*
编程题:
实现两个变量的数据进行交换
举例
int a = 10 ;
int b = 20 ;
最终要将a和b进行交换
位异或一个特点(必须记住):
一个数据被另一个数据如果位异或两次,其值是它本身!
*/
class OperatorTest{
public static void main(String[] args){
//定义两个变量
//int a = 10 ;
//int b = 20 ;
//System.out.println("a:"+a) ;
//方法1:使用中间第三方变量(最常用的一种方式)
//定义临时变量temp
//记录a的值
//int temp = a ;//(把a的值赋值给temp)
//a = b ;//(把b的值赋值给a)
//b = temp ; //(把temp的值赋值给b)
//System.out.println("a:"+a+",b:"+b+",temp:"+temp) ;//a:20,b:10,temp:10
//方法2:位异或的一个特点(必须记住):一个数据被另一个数据如果位异或两次,其值是它本身!
//先说这个特点:
//定义两个变量
//int a = 10 ;
//int b = 20 ;
//System.out.println(a^ b ^ b) ;// 10
//System.out.println(a^ b ^ b) ;// 20
/*
a^b^b:
10的二进制:
00000000 00000000 00000000 00001010
20的二进制:
00000000 00000000 00000000 00010100
-------------------------------------------
00000000 00000000 00000000 00011110
:30
00000000 00000000 00000000 00011110
00000000 00000000 00000000 00010100
-------------------------------------------
00000000 00000000 00000000 00001010
结果:10
*/
//所以方法2的计算是:
int a = 10 ;
int b = 20 ;
a = a ^ b ;//a------> a^b
b = a ^ b ;//b = a ^ b ^ b , b = a
a = a ^ b ;//此时 a = a ^ b , b = a ,将其代入, a = a ^ b ^ a , a = b
//所以a:20,b:10 两者的数值进行了交换
//我自己的思考,那能不能直接写成底下这样呢?不行的
//b = a ^ b ^ b ; // b = a , b:10
//a = a ^ b ;// a = a ^ a , a:0
//那能不能直接写成底下这样呢?更不行
//b = a ; b:10
//a = b ; a:10
System.out.println("a:"+a+",b:"+b) ;
}
}
/*
其他的位运算符:移位符号
<<:左移
将这个数据(补码)向左移动,将高位丢弃掉,右边补0
快速应用:将<<这个符号左边的数据乘以2的移动次幂
面试题:
请用有效的方式快速写出 2乘以2的3次幂:16
2 << 3 2左移3位
>>:右移
将这个数据(补码)向右移动,最高位是1,左边补1;最高位是0,左边补0
快速使用:
将>>符号左边的数据除以2的移动次幂
>>>:无符号右移
无论最高位是1还是0,那么在左边始终补0
*/
class OperatorDemo{
public static void main(String[] args){
System.out.println(3 << 2) ;//意思是将3左移两位 //3乘2的2次方 结果:12
System.out.println(24 >> 2);//24/2的2次方 结果:6
System.out.println(-24 >> 2);//-24/2的2次方 结果:-6
System.out.println(-24 >>> 2);//结果:1,073,741,818
/*
1) 3 << 2 将这个数据(补码)向左移动,将高位丢弃掉,右边补0
将3对应二进制(原码)
00000000 00000000 00000000 00000011 << 2 向左移动2位
(00)000000 00000000 00000000 00000011
(00)丢掉
000000 00000000 00000000 0000001100
右边补0
结果为12
2) 24 >> 2 将这个数据(补码)向右移动,最高位是1,左边补1;最高位是0,左边补0
00000000 00000000 00000000 00011000 >>2 向右移动2位
00000000 00000000 00000000 000110(00)
(00)丢掉
0000000000 00000000 00000000 000110
左边补0
结果为6
3) -24>>2 负数的最高位是1
10000000 00000000 00000000 00011000 (原码)
最高符号位 数值位
1 0000000 00000000 00000000 00011000 (原码)
1 1111111 11111111 11111111 11100111 (原码求反码:符号位不变,数值位按位取反)
+ 1 (反码求补码,末尾+1)
---------------------------------------------------------------
1 1111111 11111111 11111111 11101000 (补码>>2)向右移动2位
111 1111111 11111111 11111111 111010(00) 补码移动的结果(最高位是1,左边补1)
再用求得的补码反推回原码
最高符号位 数值位
1 111111111 11111111 11111111 111010 (补码)
(补码求反码,末尾-1)
- 1
---------------------------------------------------------------
1 111111111 11111111 11111111 111001 (反码)
1 000000000 00000000 00000000 000110 (反码求原码:符号位不变,数值位按位取反)
- 6
结果为-6
3) -24 >>> 2 无论最高位是1还是0,那么在左边始终补0
-24的原码:
10000000 00000000 00000000 00011000
-24的补码:
11111111 11111111 11111111 11101000 (>>>2)
0011111111 11111111 11111111 111010(00) (右移2位后的补码)
再通过补码求反码求原码(最高符号位是0,补码反码原码相同)
原码就是:0011111111 11111111 11111111 111010
结果:1,073,741,818
*/
}
}
3.三元运算符
/*
三元运算符---(三目运算符)
二目运算符 int m = 20, n =10;
单目运算符 int a = 20
三元运算符的格式:
(表达式)?执行 true 结果:执行false的结果 ;
表达式:可以简单可以非常复杂
流程:
首先判断表达式是否成立,如果成立,则执行true的结果
如果不成立,则执行false的结果
举例:
1)比较两个数据中的最大值;
2)比较两个数据中的最小值;
2)比较三个数据中的最大值;
*/
class OperatorDemo{
public static void main(String[] args){
//1)比较两个数据中的最大值;
int a = 10 ;
int b = 20 ;
//(表达式)?执行 true 结果:执行false 的结果
int max = (a>b)?a:b ;
System.out.println(max) ;// 20
System.out.println("-----------------------") ;
//2)比较两个数据中的最小值;
int min =(a<b)?a:b ;
System.out.println(min) ;// 10
System.out.println("-----------------------") ;
//3)比较三个数据中的最大值;
int x = 20 ;
int y = 40 ;
int z = 10 ;
//方法1:使用中间变量(推荐使用)
int temp = (x>y)?x:y ;
int max2 = (temp>z)?temp:z ;
System.out.println(max2) ;//40
System.out.println("-----------------------") ;
//方法2:三元运算符是可以嵌套的 (一步走)
int max3 = (x>y)? ((x>z)?x:z):((y>z)?y:z) ; //了解:去掉符号也可以运算出来 int max3 = x>y? x>z?x:z:y>z?y:z ;
//先搭骨架:(x>y)?():()
//x和y比较,x比y大,拿x和z比较: (x>z)?x:z
//x和y比较,x比y小,拿y和z比较: (y>z)?y:z
//(x>y)?():()=(x>y)?((x>z)?x:z):((y>z)?y:z);
System.out.println("三个数据中的最大值是:"+max3) ;// 三个数据中的最大值是:40
//4)比较三个数据中的最小值;
//方法1:
int temp2 = (x<y)?x:y ;
int min2 = (temp2<z)?temp2:z ;
System.out.println("三个数据中的最小值是:"+min2) ;
//方法2:
int min3 = (x<y)?((x<z)?x:z):((y<z)?y:z) ;
System.out.println("三个数据中的最小值是:"+min3) ;
}
}
4.键盘录入
/*
在写程序过程中,想让程序更加灵活(可以录入一些数据进行计算)可以使用Scanner类:
jdk提供的这个类---作用: "一个简单的文本扫描器"
目前:录入int类型数据
操作步骤
1)导包 import(关键字) java.util.Scanner ;表示需要在我当前的代码中使用Jdk提供的这个类scanner
该格式必须在class类上面
2)创建一个文本扫描器对象(键盘录入对象)
固定格式
Scanner 对象名 = new Scanner(System.in);
3)友情提示并录入int类型数据
System.out.println("请您输入一个数据:");
int 接收的变量名 = 对象名.nextInt(); //nextInt();键盘录入Scanner的一个方法,表示录入的是一个int类型
4)然后将"接收的变量名"输出出来
*/
import java.util.Scanner ;
class ScannerDemo{
//上面不能直接起为scanner,scanner是Jdk提供的类(一个简单的文本扫描器),写成scanner就找不到了
public static void main(String[] args){
//2)创建一个文本扫描器对象(键盘录入对象)
//固定格式
//Scanner 对象名 = new Scanner(System.in);
Scanner sc = new Scanner(System.in) ;
//3)友情提示并录入int类型数据
System.out.println("请您输入一个数据(int):");
//int 接收的变量名 = 对象名.nextInt();
int a = sc.nextInt() ;
//4)将"接收的变量名"输出出来,输出a,看下效果
System.out.println("a的值是:"+a) ;
}
}
/*
随堂练习
比较两个数据的最大值,然后优化--使用键盘录入两个数据
*/
//导包
import java.util.Scanner ;//在Java中只要这些类不是Java.lang包下的都需要import
class Test{
public static void main(String[] args){
Scanner sc = new Scanner(System.in) ;
System.out.println("请您输入第一个数据:") ;
int firstNum = sc.nextInt() ;
System.out.println("请您输入第二个数据:") ;
int SecondNum = sc.nextInt() ;
int max = (firstNum>SecondNum)?firstNum:SecondNum ;
System.out.println("两个数据中的最大值是:"+max) ;
}
}
5.流程语句录入