时间:2023-02-24 09:16:13 | 栏目:JAVA代码 | 点击:次
? 之前我们学习的基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入。java.util.Scanner 是java5的新特征,我们可以通过Scanner类来获取用户的输入
基本语法:
Scanner s = new Scanner(System.in);
//有些代码大家可能不理解,比如这个new,大家目前先不用理解代码的意思,先学会跟着操作,之后我们讲面向对象的时候你就会逐一明白这些代码每一个具体的意思
? 通过 Scanner 类的 next() 与 nextLine() 方法获取输入的字符串,在读取前我们一般需要使用 hasNext() 与 hasNexLine() 来判断是否还有输入的数据。
? 下面我们来实践一下加深理解和记忆
使用next方式读取:
package com.xiaodi.operator.scanner; import java.util.Scanner; public class Demo01 { public static void main(String[] args){ //创建一个扫描器对象 用于接收键盘数据 //使用IDEA开发工具输入Scanner之后回车,它就会自动导入这个类import java.util.Scanner; //我们之前一直用的是System.out是输出;System.in是输入 //这里引用了Scanner数据类型 //通过new Scanner(System.in);接收用户的输入,并且把它封装成了scanner对象 Scanner scanner = new Scanner(System.in); //输出一行字 System.out.println("使用next()方法接收:"); //判断用户有没有输入字符串 //if语句还没学,if就是如果的意思 //如果scanner这个对象有没有用户输入,(==true不写就是默认上节课讲过,一般新手才会加)有的话就使用执行里面的语句 if (scanner.hasNext()){ //使用next方式接收用,并封装给数据类型为String的str变量 String str = scanner.next(); //输出用户输入的内容 System.out.println("输入的内容为:"+str); } //凡是属于IO流的类如果不关闭会一直占用资源,要养成好习惯用完就关 scanner.close(); } }
? 我们运行起来之后,他会显示使用next方式读取,然后等待你输入字符串,我输入hello world返回输入的内容为:hello;然后程序结束
? String str = scanner.next();这句代码执行完程序会等待用户输入完毕,如果你没去输入数据那么程序就会一直卡在那
? 但是有没有发现我们输入的hello world它只输出了一个hello
刚才我们使用的是next(),现在我们使用nextLine()试一下:
package com.xiaodi.operator.scanner; import java.util.Scanner; public class Demo02 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("使用nextLine()方法读取:"); if (scanner.hasNext()) { //使用nextLine()方式读取,并封装给数据类型为String的str变量 String str = scanner.nextLine(); System.out.println("输入的内容为:"+str); } scanner.close(); } }
这次输入hello world,返回的也是hello world
那我们来看一下next()和nextLine()两种接收用户输入到底有上面区别
next():
? 例如我输入: hello;则返回:hello
只有输入有效字符后才将其后面输入的空白作为分隔符或结束符
next() 不能读取带有空格的字符串
nextLine():
我们还没有学习到if上面的代码看起来会比较复杂,我下面写一个不用if语句和判断用户输入方法的的代码,让大家自己分析,我就不写注释了
package com.xiaodi.operator.scanner; import java.util.Scanner; public class Demo03 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入数据:"); String str = scanner.nextLine(); System.out.println("输入的内容为:"+str); scanner.close(); } }
以上内容请务必掌握!!!
万一我们需要用户输入指定类型的数据,那该怎么判断用户输入的是否是我们指令类型的数据
我们在IDEA定义好scanner对象后;输入scanner.后会跳出很多方法出来
比如scanner.hasNextInt() :这样就是判断是否输入的是Int类型;这样我们就能配合if...else...语句来使用;if...else...就是如果就否则就的意思。
读取数据的方法也要变成scanner.nextInt()
下面我们来演示一下
package com.xiaodi.operator.scanner; import java.util.Scanner; public class Demo04 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int i = 0; float f = 0.0F; //提示用户输入 System.out.println("请输入数据:"); //使用hasNextInt()方法判读用户输入的数据是否为Int类型 if (scanner.hasNextInt()) { //使用nextInt()方法读取Int数据,并赋值给i(这里因为i我们上面已经定义了所以不用在指定类型) i = scanner.nextInt(); System.out.println("输入的数据为:"+i); }else { System.out.println("请输入整数类型的数据!"); String a = scanner.nextLine(); } //使用hasNextFloat()方法判读用户输入的数据是否为Float类型 if (scanner.hasNextFloat()) { //使用nextFloat()方法读取float数据,并赋值给f(这里因为f我们上面已经定义了所以不用在指定类型) f = scanner.nextFloat(); System.out.println("输入的数据为:"+f); System.out.println("请输入小数类型的数据!"); scanner.close(); } }
运行的结果为:
第一种情况:
? 请输入数据:
? 1
? 输入的数据为:1
? 请输入数据:
? 1.2
? 输入的数据为:1.2
第二种情况
请输入数据:
xiaodi
请输入整数类型的数据!
请输入数据:
xiaodi
请输入小数类型的数据!
有没有发现我在第一个if...else...语句中的else中加了一行代码
String a = scanner.nextLine();
你不加这行代码的话,你运行起来,你第一个数据输入错误了,它会直接将第一个数据拿到第二次做判断,导致你第二次不能输入数据。(
案例:
? 我们可以输入多个数字,并求其总和与平均数,每输入一个数字用回车确认,通过输入输入非数字来结束输入并输出执行结果
package com.xiaodi.operator.scanner; import java.util.Scanner; public class Demo05 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); //和,有可能会输入小数,所以使用double类型 double sum = 0.0; //个数,因为最后要求平均值,平均值就是和除以个数 int m = 0; //使用while循,判断是否输入数字,如果是就一直循环获取用户输入,如果不是则退出循环 while (scanner.hasNextDouble()) { //获取用户输入,并赋值给i double i = scanner.nextDouble(); //把和加上获取的输入 sum = sum + i; //个数加1 m = m + 1;//m++ System.out.println("您输入了第"+m+"个数据当前的总和为:"+sum); } //输出总和和平均数 System.out.println("您输入的数据的总和为:"+sum); System.out.println("您输入的数据的平均数为:"+(sum / m)); scanner.close(); } }
运行结果:
? 10.5
? 您输入了第1个数据当前的总和为:10.5
? 19.5
? 您输入了第2个数据当前的总和为:30.0
? 30
? 您输入了第3个数据当前的总和为:60.0
? 40
? 您输入了第4个数据当前的总和为:100.0
? x
? 您输入的数据的总和为:100.0
? 您输入的数据的平均数为:25.0
? 其中while循环还不懂没关系,你先跟着我的代码写一遍,等一下学到你再回来看一下,你就会恍然大悟,原来是这个样子的!
Java的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行
顺序结构是最简单的算法结构
语句与语句之间,框与框之间是按从上到下的顺序进行的,它是又若干个依次执行的处理步骤组成的,它是任何一个算法都离不开的一种基本算法结构
if单选择结构
? 我们很多时候需要去判断一个东西是否可行,然后我们才去执行,这样一个过程在程序中用if语句来表示
语法:
if (布尔表达式) { //如果布尔表达式为true将执行的语句,如果为false则跳过if语句 }
演示:
package com.xiaodi.operator.struct; import java.util.Scanner; public class Demo01 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入内容:"); String s = scanner.nextLine(); //equals:判断字符串是否一致的方法,是字符串的一种方法 if (s.equals("Hello")) { System.out.println(s); } System.out.println("End"); scanner.close(); } }
第一次输入Hello则执行if语句结果如下:
? 请输入内容:
? Hello
? Hello
? End
第二次输入XiaoDi则跳过if语句结果如下:
? 请输入内容:
? XiaoDi
? End
if双选择结构
? 那现在有一个需求,学校要一个输入分数来判定学生成绩是否及格的程序,>=60分为及格,<60分为不及格。这样的需求用一个if就搞不定了,我们需要有两个判断,需要一个双选择结构,所以就要使用if-else结构
语法:
if (布尔表达式) { //如果布尔表达式值为true执行的代码 }else { //如果布尔表达式值为false执行的代码 }
演示:
package com.xiaodi.operator.struct; import java.util.Scanner; public class Demo02 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入你的分数:"); int score = scanner.nextInt(); if (score>=60) { System.out.println("及格"); }else { System.out.println("不及格"); } scanner.close(); } }
第一个同学考了10分(走了else的分支)结果如下:
? 请输入你的分数:
? 10
? 不及格
第二个同学考了90分(走了if的分支)结果如下:
? 请输入你的分数:
? 90
? 及格
if多选择结构
? 我们发现刚才的代码不符合实际情况,真实的情况还可能存在SABCD,存在区间多级判断。比如90-100就是S,80-90就是B..等等,在生活中我们很多时候的选择也不仅仅只有两个,所以我们需要一个多选择结构来处理这类问题!
语法:
if (布尔表达式1){ //如果布尔表达式1的值为true执行的代码 }else if { //如果布尔表达式2的值为true执行的代码 }else if { //如果布尔表达式2的值为true执行的代码 }else { //如果以上布尔表达式都不为true执行的代码 }
演示:
package com.xiaodi.operator.struct; import java.util.Scanner; import java.util.SortedMap; public class Demo03 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入你的成绩:"); int score = scanner.nextInt(); if (score<40 && score>=0) { System.out.println("你的成绩评级为:D"); }else if (score>=40 && score<60) { System.out.println("你的成绩评级为:C"); }else if (score>=60 && score<80) { System.out.println("你的成绩评级为:B"); }else if (score>=80 && score<90) { System.out.println("你的成绩评级为:A"); }else if (score>=90 && score<=100) { System.out.println("你的成绩评级为:S"); }else { System.out.println("本次评级的分数为0-100,请输入正确的成绩"); } scanner.close(); } }
太多分支,可以自己执行看看!我这里就不演示执行结果了!会使文章看起来怪怪的
嵌套的if结构
使用嵌套的if...else语句是合法的。也就是你可以在另一个if或 else if语句中使用if或else if语句,你可以像if语句一样嵌套else if...else
语法:
if (布尔表达式1) { //如果布尔表达式1的值为true执行的代码 if (布尔表达式2) { //如果布尔表达式2的值为true执行的代码 } }
? 有时候我们在解决一些问题的时候,可以缩小操作范围,它可以通过层级来判断,提高效率
? 比如我们现在有一个需求:要查找1-100之间这样的一个数字,这样的话是比较麻烦的;
? 我们最笨的方法就是将用户输入的数字去1-100之间一个一个的对比,但是万一他输入了100,那程序就要对比到100才能成功,这样就会花费更多的资源和时间;我们就可以用if嵌套来判断,把这个100分成1-50,50-100去判断用户输入的值在哪个里面,或者分成更多份去判断;
我们生活在这个大数据时代,我们应该不断去思考如何提高我们程序的效率,或许哪一天你就想出来了能够提高效率的算法那你将在程序的历史上留下一些痕迹了!
记住一点:我们流程控制语句都可以相互嵌套而互不影响
? 多选择结构还有一个实现方法就是switch case语句。
? switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支
语法:
switch(expression) { case value : //语句 break; //可选 case value : //语句 break //可选 default : //可选 语句 }
switch语句中的变量类型可以是:
? byte、short、int或char
? 从Java SE7开始,switch支持String类型了
? 同时case标签必须在为字符串常量或字面量
演示:
package com.xiaodi.operator.struct; public class SwitchDemo01 { public static void main(String[] args) { char grade = 'C'; switch (grade) { case 'A' : System.out.println("优秀"); break; //可选 case 'B' : System.out.println("良好"); case 'C' : System.out.println("及格"); case 'D' : System.out.println("再接再厉"); case 'E' : System.out.println("挂科"); } } }
当grade为C时运行如下:
? 及格
? 再接再厉
? 挂科
当grade为A时运行如下:
? 优秀
为什么会这样,我说过这个break是可选的,如果不写break他就会执行匹配到的分支以及后面的分支直到遇到break,如果没遇到,就会直接执行到最后;这种现象叫做case穿透;(所以要养成一个好习惯,写完每一个case后面都应该加一个break(除非特殊需求))
我们还可以来一个default
package com.xiaodi.operator.struct; public class SwitchDemo01 { public static void main(String[] args) { char grade = 'F'; switch (grade) { case 'A' : System.out.println("优秀"); break; //可选 case 'B' : System.out.println("良好"); break; //可选 case 'C' : System.out.println("及格"); break; //可选 case 'D' : System.out.println("再接再厉"); break; //可选 case 'E' : System.out.println("挂科"); break; //可选 default : System.out.println("未知等级"); } } }
当grade不等于任何一个case的时候就会执行default分支;
? 跟if比起来switch是有一些好处的,它在执行case语句的时候会先匹配,匹配成功就会返回当前case的值,然后再根据它是否有break判断是否继续输出。if是判断匹配区间,而switch是匹配一个具体的值!
接下来演示JDL7开始才支持的字符串类型:
package com.xiaodi.operator.struct; public class SwitchDemo02 { public static void main(String[] args) { String name = "晓迪"; switch (name) { case "小迪" : System.out.println("小迪"); break; case "晓迪" : System.out.println("晓迪"); default : System.out.println("神马东西??"); } } }
运行结果为:晓迪
还记不记得我之前讲过字符的本质还是数字,给大家讲一个东西反编译
什么叫反编译:比如.java文件编译成.class文件,这个class文件叫做字节码文件是人类看不懂的,我们要看懂就要进行反编译
反编译教程:
? 使用IDEA,点开享目结构(File-->Project Structure),就能看到Compiler output,将地址复制到文件管理器,打开找对对应需要反编译的文件,你可以使用notepad++打开看一下,你会发现看不懂,没事我也看不懂。
? 在IDEA文件夹那边右键,选择Open ln,再选择Explorer打开对应文件夹,把class文件复制进去,在IDEA双击这个字节码文件,选择Accept,这个就是反编译之后的
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) package com.xiaodi.operator.struct; public class SwitchDemo02 { public SwitchDemo02() { } public static void main(String[] args) { String name = "晓迪"; byte var3 = -1; switch(name.hashCode()) { case 767419: if (name.equals("小迪")) { var3 = 0; } break; case 848887: if (name.equals("晓迪")) { var3 = 1; } switch(var3) { case 0: System.out.println("小迪"); case 1: System.out.println("晓迪"); default: System.out.println("神马东西??"); }
? 你会发现 switch (name) {} 变成了 switch(name.hashCode()) {} ; case "晓迪" : 变成了 case 848887: ,也就是说它进行编译之后是通过hashCode()进行判断的,什么是hashCode(),你现在可以理解为每一个对象都有一个hashCode,它是通过一些特定算法生成的,而我们case后面的字符串中文都会有一个自己对应的hash值,然后它就判断这个hash值是否跟name的hash值相同,这就是JDK7新特性的原理
while是最基本的循环,她的结构为:
while (布尔表达式) { //循环内容 }
演示输出1-100:
package com.xiaodi.operator.struct; public class WhileDemo01 { public static void main(String[] args) { int i = 0; while (i<100) { i++;//i = i + 1; System.out.println(i); } } }
运行会输出1-100
演示死循环:
package com.xiaodi.operator.struct; public class WhileDemo02 { public static void main(String[] args) { while (true) { System.out.println(1); } } }
运行会无限输出1 直到程序崩溃
演示:计算1+2+3+...+100=?
package com.xiaodi.operator.struct; public class WhileDemo03 { public static void main(String[] args) { int i = 0; int sum = 0; while (i<100) { i++; sum = sum + i; } System.out.println(sum); } }
结果5050
其中while循环还能像下面这样写自己思考一下有什么不同
while (i<=100) { sum = sum + i; i++; }
语法:
do { //代码语句 }while (布尔表达式);
同样是1+2+3...+100,看看DoWhile是怎么实现的吧!
package com.xiaodi.operator.struct; public class DoWhileDemo01 { public static void main(String[] args) { int i = 0; int sum = 0; do { i++; sum = sum + i; }while (i<100); System.out.println(sum); } }
While和do-While的区别:
演示:两者区别
package com.xiaodi.operator.struct; public class DoWhileDemo02 { public static void main(String[] args) { int a = 0; int sum = 0; while (a<0) { System.out.println(a); a++; } System.out.println("==========="); do { }while (a<0); } }
输出结果为:
? ===========
? 0
虽然所有的循环结构都可以用while或者do...while表示,但java提供了另一种语句 for循环,使一些循环结构变得更加简单
for循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环结构
在IDEA直接输入100.for然后回车能快捷生成
for循环执行的次数是在执行前就确定的。语法格式如下:
for (初始化;布尔表达式;迭代) { //代码语句 }
实例:
package com.xiaodi.operator.struct; public class ForDemo01 { public static void main(String[] args) { int a = 1;//初始化条件 while (a<=100) { //布尔表达式 System.out.println(a);//输出a a+=2; //迭代 } System.out.println("while循环结束"); //初始化;布尔表达式;迭代 for (int i=0;i<=100;i++) { System.out.println(i); System.out.println("For循环结束"); } }
for的死循环
package com.xiaodi.operator.struct; public class ForDemo02 { public static void main(String[] args) { for (;;) { } } }
练习1:计算0-100之间的基数和偶数的和;
package com.xiaodi.operator.struct; public class ForDemo03 { public static void main(String[] args) { int oddSum = 0; int evenSum = 0; for (int i=0;i<100;i++) { if (i%2!=0) { //奇数 oddSum+=i; }else { //偶数 evenSum+=i; } } System.out.println("0-100之间的奇数和:"+oddSum); System.out.println("0-100之间的偶数和:"+evenSum); } }
练习2:用while或for循环输出1-1000之间能被5整除的数,并且每行输出3个
第一种方法:
package com.xiaodi.operator.struct; public class ForDemo04 { public static void main(String[] args) { for (int i=0;i<1000;i++) { if (i%5==0) { System.out.print(i+"\t"); } if (i%(3*5)==0) { System.out.println(); //System.out.print("\n"); } } //println 输出完会换行 //print 输出完不会换行 } }
第二种方法:
package com.xiaodi.operator.struct; public class ForDemo04_1 { public static void main(String[] args) { for (int i = 0; i < 1000; i+=5) { System.out.print(i+"\t"); if (i%(3*5)==0) { System.out.println(); } } } }
? 这些练习不一定要用我写的方法才能实现,大家也可以多思考,主要思路肯定是循环
至于我为什么这题要写两种方法呢?
? 我们可以在不影响程序正常工作的条件下,减少程序运行所需资源
练习3:打印99乘法表
package com.xiaodi.operator.struct; //效果如下 //1*1=1 //1*2=2 2*2=4 //1*3=3 2*3=6 3*3=9 //1*4=4 2*4=8 3*4=12 4*4=16 //1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 //1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 //1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 //1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 //1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81 public class ForDemo05 { public static void main(String[] args) { //1、我们先打印第一列,这个大家应该都会 //for (int i = 1; i <= 9; i++) {System.out.println("1*"+i+"="+(1*i));} //2、我们把固定的1再用一个循环包起来 //使用for (int j = 1; j <= 9; j++) {}把上面的包起来 把固定的1换成循环的j //3、去掉重复项, //i<=j //4、调整样式 //使用print使其不换行 间隔用"\t" //里面的循环每次完成一次则输出一次换行 System.out.println(); for (int j = 1; j <= 9; j++) { for (int i = 1; i <= j; i++) { System.out.print(i+"x"+j+"="+(j*i) + "\t"); } System.out.println(); } } }
? 这道题主要学习思路,学会把一个大问题拆分成若干个小问题,逐一攻破!,这也是我们以后开发项目的一个基本思路!
语法:
for (声明语句 : 表达式) { //代码句子 }
声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配,其作用域限定在循环语句块,其值与此时数组元素的值相等
表达式:表达式是要访问的数组名,或者是返回值为数组的方法。
演示:
package com.xiaodi.operator.struct; public class ForDemo06 { public static void main(String[] args) { int[] numbers = {10, 20, 30, 40, 50}; //定义了一个数组 //遍历数组的元素 for (int x:numbers) { System.out.println(x); } } }
分析:把numbers这个数组每一项遍历出来,赋值给int x,每次循环x就从numbers中取值
我们用普通for循环演示一下 上面的操作,上面使用的增量型for循环就是用来简化下面的操作,核心原理是一样的,大家简单理解一下
package com.xiaodi.operator.struct; public class ForDemo07 { public static void main(String[] args) { int[] numbers = {10, 20, 30, 40, 50}; for (int i = 0;i<5;i++) { System.out.println(numbers[i]); } } }
现在能理解当然是最好的了,不理解也没关系,我们现在只是让大家知道一下我们以后会学一个这样简化的东西!不理解不必深究!
演示:
package com.xiaodi.operator.struct; public class BreakDemo01 { public static void main(String[] args) { int i = 0; while (i<100) { i++; System.out.println(i); if (i==30) { //如果i等于30的时候,则跳出循环体 break; } } System.out.println("123"); //证明break只是跳出循环体 } }
break只是跳出循环,程序还会继续执行。
演示:
package com.xiaodi.operator.struct; public class ContinueDemo01 { public static void main(String[] args) { int i = 0; while (i<100) { i++; if ((i%10)==0) { //如果i能被10整除,则输出换行,然后跳过当前这次循环 System.out.println(); continue; } System.out.print(i+"\t"); } } }
通过上面的演示,break可以理解为,我不干了;continue可以理解为,我不干了第二天又怂了又回来继续干
打印5行的三角形
解题思维:
我们把三角形切一下,然后分部完成
第一步打印1
package com.xiaodi.operator.struct; public class TestDemo01 { public static void main(String[] args) { for (int i = 1; i <= 5; i++) { for (int j = 5; j >= i; j--) { System.out.print("*"); } System.out.println(); } } }
第二部打印2,然后把第一步打印的内容变为空格
package com.xiaodi.operator.struct; public class TestDemo01 { public static void main(String[] args) { for (int i = 1; i <= 5; i++) { for (int j = 5; j >= i; j--) { System.out.print(" "); } for (int j = 1; j <= i; j++) { System.out.print("*"); } System.out.println(); } } }
第三步打印第三部分
package com.xiaodi.operator.struct; public class TestDemo01 { public static void main(String[] args) { for (int i = 1; i <= 5; i++) { for (int j = 5; j >= i; j--) { System.out.print(" "); } for (int j = 1; j <= i; j++) { System.out.print("*"); } for (int j = 1; j < i; j++) { System.out.print("*"); } System.out.println(); } } }
如果不理解使用IDEA中的Debug
? 在你不理解的行开始打上断点,就是在行号后面点一下,然后点击小虫子图标,然后程序运行到断点会停住,然后通过↓这个符号一步一步的去运行下去,去一步一步理解!点击console能看见当前输出的结果