Java基础 Day04
三目运算符
-
单目运算符:++ – !
-
双目运算符:+ - & >
-
三目运算符格式:布尔表达式 ? 表达式1 : 表达式2
-
布尔表达式:要求结果类型必须是Boolean类型 true false
-
执行流程:
- 先执行表达式
- true,则执行表达式1
- false 则执行表达式2
- 先执行表达式
-
案例:
1、判断变量num是否大于0
2、判断变量num是奇偶数
3、获取num1和num2的最大值
4、获取num1、num2、num3的最大值
位运算符
位操作是程序设计中对位模式按位或二进制数的一元和二元操作。
位运算符用来对二进制位进行操作。
注:开发使用的不多,源码中大量使用位运算,了解即可
位运算符包括:& | ^ ~
位移运算符包括:<< >> >>>
1. & 按位与
-
概念:
- 将两个运算的整数转为二进制,按位执行与运算
- 当两个都为1时,结果为1;如果有0,则结果为0;即**“有0为0,全1为1”**
- 技巧:可以理解为按位乘
- 负数以补码形式参加按位与运算
-
常见用途:
- 清零。如果想将一个单元清零,即使其全部二进制位为0,只要与一个各位都为零的数值相与,结果为零。
- 取一个数中指定位
- 方法:找一个数,对应X要取的位,该数的对应位为1,其余位为零,此数与X进行“与运算”可以得到X中的指定位
- 例:设X=10101110,取X的低4位,用 X & 0000 1111 = 0000 1110 即可得到
2. | 按位或
-
概念:
- 将两个运算的整数转为二进制,按位执行或运算
- 当两个都为0时,结果才为0,只要有1,结果就为1,即**“有1为1,全0为0”**
- 技巧:可以理解为按位加
- 负数以补码形式参加按位或运算
-
常见用途:
- 将一个数据的某些位 置1
- 方法:找到一个数,对应X要置1的位,该数的对应位为1,其余位为零。此数与X相或可使X中的某些位置1
- 例:将X=10100000的低4位置1 ,用 X | 0000 1111 = 1010 1111即可得到。
3 ^ 按位异或
-
概念:
- 如果两个相等则为0;如果两个不相等则为1;
- "相异为1,相同为0"
-
常见用途:
- 使特定位翻转
- 找一个数,对应X要翻转的各位,该数的对应位为1,其余位为零,此数与X对应位异或即可
- 例:X=10101110,使X低4位翻转,用X ^ 0000 1111 = 1010 0001即可得到
- 与0相异或,保留原值,X ^ 0000 0000 = 1010 1110
- 使特定位翻转
4 ~ 非 按位取反
- 概念:
- 单目运算符
- 对1取反为0,21
- 技巧:对一个数按位取反的值为该数+1后再乘以-1
5 << 左移运算符
- 概念:
- 格式:a<<b
- 将a二进制位按位依序左移b位
- 先将整数转为二进制,然后将二进制数整体向左移动相应的位数,左侧多出来的位数直接舍弃,右侧空出来的位数补0
- 技巧:对一个十进制数左移n位后得到的值为该数乘以2^n的积
6 >> 右移运算符
- 概念:
- 格式:a>>b
- 将a二进制位按位依序右移b位
- 先将整数转为二进制,然后将二进制数整体向右移动相应的位数,右侧多出来的位数直接舍弃,左侧空出来的位数,如果当前为负数则补1,如果当前时正数,则补0;
- 技巧:
- 正数或可被2整除的负数:数字>>n=数字/2^n
- 不可被2整除的负数:数字>>n=数字/2^n+(-1)
7 >>> 无符号右移
- 概念:
- 格式:a>>>b
- 将a二进制位向右无符号移动b位
- 先将整数转为二进制,然后将二进制数整体向右移动相应的位数,右侧多出来的位数直接舍弃,左侧空出来的位数补0;
Scanner
掌握如何使用即可
步骤:
1、导包–用的是哪个包下的Scanner
java.util.Scanner
格式:
import java.util.Scanner;
-
通知编译器,使用的Scanner类和其中的成员在哪。
-
在Java中除了使用java.lang下的类以外,都需要进行import操作
位置:
定义类的上边
注意:import关键字
2、创建Scanner的对象(变量)
Scanner sc = new Scanner(System.in);
位置:
main方法中
3、调用对象的方法
nextInt()–获取用户输入的整数,返回int类型数据
nextDouble()–获取用户输入的浮点数,返回double类型
next()–获取用户输入的字符串,返回String类型数据
格式:
变量 = 对象.方法名();
4、关闭Scanner
格式:
对象.close();
练习:
需求:
- 程序启动后,让用户输入期望薪资-> double类型
- 之后让用户输入工作年限-> int类型
- 让用户输入性别 -> String类型
- 确定工资标准
- 如果年限大于等于3,工资翻倍
- 如果是女性,工资额外加2000
- 输出最终工资
控制结构
包括:顺序结构、分支结构、循环结构
顺序结构
从上到下 从左到右依次执行
最常用 最基本的控制结构
分支结构
if 判断语句
- 格式一:
if(判断条件){
// 当判断条件成立时,需要执行的代码;
}
-
判断条件:结果必须为布尔型,true代表条件成立;false 条件不成立
-
执行流程:
- 判断条件
- true,则执行if代码块中的代码
- false,则if语句结束
- 判断条件
- 格式二:
if(判断条件){
// 成立时的代码块;
}else{
// 不成立时的代码块;
}
- 注:不存在独立的else,一定是与一个if相关联
- 格式三:
if(判断条件1){
// 当判断条件1成立时执行的代码块;
}else if(判断条件2){
// 当判断条件1不成立且判断条件2成立时要执行的代码块;
}else if(判断条件3){
// 当判断条件1不成立且判断条件2不成立且判断条件3成立时要执行的代码块;
}else{
// 当所有的判断条件都不成立时,执行当前的代码块;
}
- 案例:
- 获取输入的成绩,根据成绩的分段输出学生的评级
- <60 不合格 60-70 合格 70-80中等 80-90 良好 90-100优秀
- if语句嵌套使用:
- if语句中嵌套if语句;
- 将内层的if理解为外层if的代码块;
案例:
获取用户输入的数,输出大于0的偶数
Scanner sc=new Scanner(System.in);
System.out.println("请输入数字:");
int i=sc.nextInt();
if(i>0 && i%2==0){
System.out.println(i);
}
案例:
获取用户输入的月份,输出该月份所属的季节;
春季:3 4 5
夏季:6 7 8
秋季:9 10 11
冬季:12 1 2
switch case 匹配语句
格式:
switch(值){
case 值1:
当值和值1匹配时要执行的代码块;
break;
case 值2:
当值和值2匹配时要执行的代码块;
break;
...
default:
当值和所有case的值都不匹配时执行的代码块;
break;
}
注意:
case穿透机制:当和某个case值匹配之后,会执行该case之后的代码,直到遇到break语句为止
在一些特殊的逻辑下,可以利用case穿透机制,使代码变得更为简洁
//1.5 1.4 1.3 1.2
String version=...;
switch(version){
case "1.2":
// 升级包包含1.3
case "1.3":
// 升级包包含1.4
case "1.4":
// 升级包包含1.5
break;
default:
// 已是最新,不用升级
break;
}
//1.5 1.4 1.3 1.2
String time=...;
switch(time){
case "7:00":
// 吃早饭
case "12:00":
// 吃午饭
// 睡午觉
case "18:00":
// 吃晚饭
case "23:00":
// 吃夜宵
// 睡觉
default:
//
break;
}
总结:有一个连贯的分成多个节点的逻辑流,需要判断从那个节点开始按顺序向后执行,就可以利用case穿透机制。
//1.5 1.4 1.3 1.2
String stage=...;
switch(stage){
case "立项":
// 项目经理和产品经理讨论需求
case "产品设计":
// 产品经理进行产品设计
case "UI设计":
// UI工程师根据产品设计生成UI设计
case "开发":
// 开发工程师根据产品设计和UI设计开发软件
case "测试":
// 测试工程师测试软件
default:
//
break;
}
Switch case支持byte short int char,JDk1.7开始支持字符串类型,枚举类型;
10086客服小程序
查询话费余额请输入1
查询套餐内剩余流量请输入2
查询积分请输入3
人工客服请输入4
案例:
简易计算器 + - * /
用户输入两个运算数 3 5
用户输入运算符 next() “+”
switch case匹配运算符
if语句和应用场景和switch case场景:
- 如果要进行范围判断,优先使用if语句
- 简单的条件判断,优先使用if语句
- switch case的可读性由于多个if-else if的组合,在几个具体的值之间进行匹配时,优先使用switch case
- switch case具有case穿透的语法,在特定场景下代码较为简洁
循环结构
循环四要素:
初始化条件 循环条件 改变循环条件的语句 循环体
while循环
格式:
// 初始化循环条件;while(循环条件){ // 循环体; // 改变循环条件的语句;}
循环条件:boolean的值,如果循环条件的值为true,则继续执行循环,如果为false,则停止循环;
执行流程:
案例:
打印10遍hello
求1+2+3+…+10的和
求1-200以内的所有偶数(能被2整除的)
补充知识:生成随机数
import java.util.Random;public class Demo7{ public static void main(String[] args){ Random ran=new Random(); while(true){ // int i=ran.nextInt(101); // 生成0~(n-1)范围内的随机整数 int i=ran.nextInt(100)+1; // 1~100的随机整数 System.out.println(i); } }}
练习:
猜数字的小游戏
需求:
-
程序启动后,随机生成一个0-100的整数,作为目标数
Random ran=new Random(); // 在后续的代码中可以复用int target=ran.nextInt(101); // 随机生成0~100的整数
-
请用户猜一个数字(输入一个数字)
-
判断用户输入的数字和目标数的关系,给出提示:
- 猜高了
- 猜低了
- 猜中了
-
如果是猜高了或猜低了,提示用户再次输入数字,即重复2-4的逻辑
-
如果用户猜中了,程序结束(初学者),
flag=false; // 循环停止
或System.exit(); // 程序退出
-
(拓展)如果用户猜中了,显示用户一共猜了多少次,并询问用户,是否重新开始
- 如果不重新开始,则停止程序
- 如果重新开始,则重新生成一个随机数作为目标数,重复2-5的 逻辑
// 导入Scanner和Randomimport java.util.Scanner;import java.util.Random;public class Demo8{ public static void main(String[] args){ // 创建Scanner对象 Scanner sc=new Scanner(System.in); // 创建Random对象 Random ran=new Random(); boolean flag1=true; // 创建一个循环 while(flag1){ // 随机生成一个数字 int target=ran.nextInt(101); boolean flag2=true; // 创建一个循环 while(flag2){ // 请用户输入一个数字 System.out.println("请猜一个数字(0-100):"); int number=sc.nextInt(); // 判断输入数字和目标数字的关系 if(number<target){ // 数字小于目标数 // 提示小了 System.out.println("猜小了"); }else if(number>target){// 数字大于目标数 // 提示大了 System.out.println("猜大了"); }else{ // 数字等于目标数 // 提示成功 System.out.println("恭喜您,猜对了!"); // 询问是否继续(Y/N) System.out.println("是否继续(Y/N)?"); // 接收用户输入 char c=sc.next().charAt(0); // 如果是N,程序结束 if(c=='N'){ flag2=flag1=false; // System.exit(0); } } } } }}
do while 循环
格式:
// 声明初始值do{ // 循环体; // 控制条件;}while(判断条件);
执行流程:
for循环
执行流程上和while一样的;
格式:
for(初始化条件语句;循环条件;改变循环条件的语句){ // 循环体;}
执行流程:
案例:
打印10遍hello
求1+2+3+…+10的和
求1-200以内的所有偶数
三种循环的区别与联系:
- 明确知道循环次数时,优先使用for循环
- 不明确循环次数,当某个条件改变时,循环终止的场景,优先使用while循环
- dowhile至少执行一次
- 三种循环等效转换
- for循环的初始值是循环内部的局部变量,在后面使用不了