一、初始计算机和Java语言
1、计算机的体系结构
a.计算机的基本概念
计算机(Computer)俗称电脑,是现代一种用于高级计算,使用非常广泛 的设备,主要由计算机硬件和计算机软件两个部分组成。 • 计算机硬件是客观存在的各种计算机相关设备,而计算机的软件是用于 控制各种硬件设备完成各种功能
b.常见的主要硬件
计算机硬件(Computer Hardware)主要包括:中央处理器(CPU)、内存、 硬盘、输入输出设备、主板、机箱和电源等辅助设备。
c.cpu的概述
CPU - 中央处理器(英文Central Processing Unit)
- 是计算机中最核心的部件,类似于人的大脑
- 是一台计算机运算核心和控制核心,所有运算都由CPU完成
- 其功能主要是解释计算机指令以及处理计算机软件中的数据
d.内存的概述
• 内存 - 是计算机中的存储部件,内存(Memory)也被称为内存储器。
- 用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据
- CPU可以直接访问内存的数据,而且效率比较高
- 容量小不能实现永久存储,一旦断电会造成数据的丢失
- 时刻记住ctrl+s快捷键进行保存
e.硬盘的概述
• 硬盘 - 是计算机中的存储部件
- 主要用于永久存放数据内容,容量大且断电不丢失
- CPU不能直接访问硬盘中数据,若希望访问则需要先加载到内存中
f.科普小知识
• 1Tb = 1024Gb
1Gb = 1024Mb
1Mb = 1024Kb
1Kb = 1024Byte (字节)
1Byte = 8Bit (二进制位)
g.输入输出设备
• 其中键盘叫做标准输入设备,显示器叫做标准输出设备。
h.系统软件
• 计算机软件(Computer Software)可分为系统软件和应用软件,系统软件 就是操作系统,是其他软件的基础。
• 主流的操作系统有:Windows/Unix/Linux/IOS/Android。
i.计算机的体系结构
2、Java语言的概述
a.计算机语言的概述
• 语言是人与人之间进行沟通的主要表达方式。如:中国人与中国人使用 用普通话沟通。而中国人要和英国人交流,就要使用英语沟通。
• 计算机语言是人与计算机之间交流的表达方式,该语言有很多种
b.计算机语言的发展
• 第一代语言:机器语言
指令以二进制代码形式存在,最开始使用穿孔卡片。
• 第二代语言:汇编语言。
使用助记符表示一条机器指令,如:ADD、SUB等。
• 第三代语言:高级语言
Java、C ,C++,PHP , Python,Scala等。
c.Java语言的江湖地位
d.Java语言的发展历史
• 1995年 Java问世。
• 1996年 Java 1.0。
• 1999年 Java 1.2发布(JAVA SE\JAVA EE\JAVA ME)。
• ... ... ...
• 2004年 Tiger 发布(JAVA5.0),Java 登录火星。
• 2011年 7月由Oracle正式发布Java7.0。
• 2014年 3月19日,Oracle公司发布Java8.0的正式版。
• 2017年 9月21日,Java9.0正式发布。
• 2018年 9月25日,Oracle官方宣布Java11正式发布。
f.桌面应用
• Java SE(Java Platform, Standard Edition)称之为“Java平台标准版”,是 Java平台的基础。
• Java SE包含了运行Java用所需要的基础环境和核心类库。
• Java SE还定义了基于桌面应用的基础类库,通过使用这些类库,我们可 以编写出类似于像Office那样的丰富多彩的桌面应用。
g.企业应用
• Java EE(Java Platform,Enterprise Edition)称之为“Java平台企业版”。
• Java EE构建在Java SE基础之上,用于构建企业级应用。所谓企业级应用 是指那些为商业组织、大型企业而创建的应用系统,例如:电信的“计费 系统”、银行的“网银系统”、企业中的“客户关系管理系统”等等。
h.移动应用
• Java ME (Java Platform,Micro Edition)称之为Java 平台微型版。
• 为机顶盒、移动电话和PDA等嵌入式消费电子设备提供的Java解决方案。 随着3G移动智能平台时代的到来,特别是以Java为核心编程语言的 Android智能平台的迅速普及,Java ME已经走向淘汰。
3、开发环境的搭建和使用(重点)
a.开发工具的下载和安装
• 下载方式
• 方式一:通过官网下载 www.sun.com www.oracle.com
• 方式二:通过搜索下载 www.baidu.com www.sogou.com
• 安装方式
• 若下载的是安装版,则一路点击下一步安装即可;
• 若下载的是绿色版,则直接解压即可;
• 无论是安装版还是绿色版,切记安装的路径中不要有中文!
b.Jdk的目录结构
• bin目录 - 该目录下主要存放JDK的各种工具命令。
• conf目录 - 该目录下主要存放jdk的相关配置文件。
• include目录 - 该目录下主要存放了一些平台的头文件。
• jmods目录 - 该目录下主要存放了JDK的各种模块。
• legal目录 - 该目录下主要存放了JDK各模块的授权文档。
• lib目录 - 该目录下主要存放了JDK工具的一些补充jar包和源代码。
c.相关的概念
• JDK - 称为Java开发工具包( Java Development Kit)。Java开发人士需 要下载和安装JDK,目前的主流版本为JDK11。
• JRE - 称之为Java SE运行时环境(Java SE Runtime Environment),提供 了运行Java应用程序所必须的软件环境等。无论是开发还是运行Java应用 都必须安装。
• javac.exe - 编译器,主要用于将高级Java源代码翻译成字节码文件。
• java.exe - 解释器,主要用于启动JVM对字节码文件进行解释并执行。
d.Jdk、jre、jvm之间的关系
e.Java开发的常用工具
• 文本编辑器(TE,Text Editor)
• 记事本、Notepad++、Edit Plus、UltraEdit、…
• 集成开发环境(IDE,Integrated Development Environment )
• Jbuilder、NetBeans、Eclipse、MyEclipse、IDEA、…
f.编写Java程序的流程
• 新建文本文档,将文件扩展名由xxx.txt修改为xxx.java;
• 使用记事本/Notepad++的方式打开文件,编写Java代码后进行保存;
• 启动dos窗口,并切换到.java文件所在的路径中;
• 使用javac xxx.java进行编译,生成xxx.class的字节码文件;
• 使用java xxx 进行解释执行,打印最终结果;
g.常见的错误
• 错误: 需要class, interface或enum => 通常都是class关键字拼写错误
• 错误: 找不到符号 => 通常因为单词拼写错误或Java中不支持这样的单词
• 错误: 需要';' => 通常都是因为少写分号,加上英文版分号即可
• 错误: 非法字符: '\uff1b' => 通常是因为出现了中文标点符号,修改为英 文版即可
• 错误: 在类 PrintTest 中找不到 main 方法, 请将 main 方法定义为: =>
main写成了mian
h.编译和运行
i.Java11新特性之简化的编译运
行
• 新建文本文档,将文件扩展名由xxx.txt修改为xxx.java;
• 使用记事本/Notepad++的方式打开文件,编写Java代码后进行保存;
• 启动dos窗口,并切换到.java文件所在的路径中;
• 使用java xxx.java 进行编译运行,打印最终结果(慎用);
j.常用的快捷键
ctrl+s 保存 ctrl+c 复制 ctrl+v 粘贴 ctrl+a 全选 ctrl+x 剪切
ctrl+z 撤销 ctrl+f 搜索 ctrl+shift 切换输入法,使用shift进行中英文切换
windows+d 回到桌面 windows+e 打开计算机 windows+l 锁屏
windows+r 打开运行,输入cmd后回车就会启动dos窗口 windows+tab 切 换任务 alt+tab 切换任务
ctrl+alt+delete 启动任务管理器
k.注释
• 注释用于进行代码说明,是给程序员看的文字描述,编译器会忽略注释。
• 基本分类
// 单行注释 ,从 // 开始,到本行结束,都是注释。
/* */ 多行注释,从/* 开始,到*/结束,中间所有都是注释。
/** */ 多行/文档注释,从/**开始,到*/结束,是一种支持提取的注释。
• 多行注释不允许嵌套使用!
l.环境变量的配置
• 基本概念
通常情况下可执行文件只能在该文件所在的路径中使用,为了使得该可 执行文件可以在任意路径中使用,则需要将该文件所在的路径信息配置到 环境变量Path中。
• 配置方式
计算机 => 右击,选择属性 => 高级系统设置 => 高级 => 环境变量 => 系统变量 => 找到Path,点击编辑 => 将javac.exe所在的路径信息配置到
Path变量值的最前面,加上英文版的分号 => 一路点击确定即可
• 注意事项
切记Path变量原来的变量值不要删除,配置完毕后记得重启dos窗口!
m.跨平台原理
• Java字节码可以通过JVM翻译为具体平台能够执行的机器指令。由于Sun 定义了JVM规范,而且不同的操作系统大多提供了JVM实现,才使得相同 的一个字节码文件可以在不同的系统上运行,从而使Java赢得了“一次编 译,到处使用”的美名。
4、总结和答疑
5、代码
public class HelloWorld{/*类体*///程序的入口,main方法public static void main(String args []){/*方法体*/System.out.println("HelloWorld");}}
二、Java语言编程基础
1、变量(重中之重)
a.变量的基本概念
• 当需要在程序中记录单个数据内容时,则声明一个变量即可,而声明变 量的本质就是在内存中申请一个存储单元,由于该存储单元中的数据内 容可以发生改变,因此得名为"变量"。
• 由于存放的数据内容大小不一样,导致所需存储单元的大小不一样,在 Java语言中使用数据类型加以描述,为了便于下次访问还需要给该变量指 定一个名字,用于记录该变量对应的存储单元。
b.变量的声明方式
• 数据类型 变量名 = 初始值;
• 其中=初始值可以省略,但;不可以省略
c.变量的注意事项
• Java是强类型语言,变量在使用前必须声明来指明其数据类型。
• 变量在使用之前必须初始化。
• 变量不能重复声明
d.标识符的命名法则(笔试)
• 由数字、字母、下划线以及$等组成,其中数字不能开头(后面讲到)。
• 不能使用Java语言的关键字,所谓关键字就是Java语言用于表示特殊含义 的单词。
• 区分大小写,长度没有限制但不宜过长。
• 尽量做到见名知意,支持中文但不推荐使用。
• 标识符可以给类/变量/属性/方法/包 起名字。
e.案例题目
• 提示用户从键盘输入自己的姓名和年龄信息并打印出来。
/*编程实现变量的输入输出*/
//导入java目录中util目录的Scanner类
import java.util.Scanner;
public class VarIOTest {public static void main (String args [] ) {// 1.声明两个变量用于记录姓名和年龄信息(局部变量需要默认值)//Sting name;//int age;// 2.提示用户从键盘输入姓名和年龄信息并放入到变量中 (变量随时使用随时声明)System.out.println("请输入你的姓名和年龄信息:");// 创建一个扫描器来扫描键盘输入的内容 System.in 代表键盘输入Scanner sc = new Scanner(System.in);// 通过扫描器读取一个字符串数据放入变量name中String name = sc.next();// 通过扫描器读取一个整数数据放入变量age中int age = sc.nextInt();// 3.打印变量数值 (尽可能减少重复的代码)System.out.println("name = " + name);System.out.println("age = " + age);System.out.println("name = " + name + ",age = " + age);}
}
f.官方库的使用
• JDK中带有大量的API类, 是有Java系统带来的工具库, 这些工具数以万计! 是Java官方程序员的技术积累。
• 使用这些类可以大大简化编程, 提高开发效率。
• 具体的API类功能, 可以参阅Java的参考手册
2、数据类型
a.数据类型的分类
• 在Java语言中数据类型主要分为两大类:
• (1)基本数据类型(记住)
byte、short、int、long、float、double、boolean、char
• (2)引用数据类型(了解) 数组、类、接口、枚举、标注
b.常用的进制
• 在日常生活中采用十进制进行数据的描述,逢十进一,十进制权重是: 10^0、10^1、10^2、...
• 在计算机的底层采用0和1组成的二进制序列进行数据的描述,逢二进一, 二进制的权重是2^0、2^1、2^2、...
• 二进制中的最高位(最左边)用于代表符号位,若该位是0则表示非负数, 若该位是1则表示负数。
• 八进制和十六进制其实都是二进制的简写。
c.进制之间的转换
• 正十进制转换为二进制的方式
a.除2取余法,使用十进制整数不断地除以2取出余数,直到商为0时将 余数逆序排序。
b.拆分法,将十进制整数拆分为若干个二进制权重的和,有该权重下面 写1,否则写0。
• 正二进制转换为十进制的方式
a.加权法,使用二进制中的每个数字乘以当前位的权重再累加起来。
• 负十进制转换为二进制的方式
a.先将十进制的绝对值转换为二进制,然后进行按位取反再加1。
• 负数的需要补码:按位取反,再加1 。
• 负二进制转换为十进制的方式
a.先减1再按位取反,合并为十进制整数后添加负号。
d.单个字节表示的整数范围(重中之重)
• 在计算机中单个字节表示八位二进制位,其中最高位(最左边)代表符号位, 使用0代表非负数,使用1代表负数,具体表示的整数范围如下:
• 非负数表示范围:0000 0000 ~ 0111 1111 => 0 ~ 127 => 0 ~ 2^7-1
• 负数表示范围:1000 0000 ~ 1111 1111 => -128 ~ -1 => -2^7 ~ -2^0
• 单个字节表示的整数范围是:-2^7 ~ 2^7-1,也就是-128 ~ 127.
e.整数类型
• Java语言中描述整数数据的类型有:byte、short、int、long,荐int类型
• 其中byte类型在内存空间中占1个字节,表示范围是:-2^7 ~ 2^7-1.
• 其中short类型在内存空间中占2个字节,表示范围是:-2^15 ~ 2^15-1.
• 其中int类型在内存空间中占4个字节,表示范围是:-2^31 ~ 2^31-1.
• 其中long类型在内存空间中占8个字节,表示范围是:-2^63 ~ 2^63-1.
• 在Java程序中直接写出的整数数据叫做直接量/字面值/常量,默认为int类 型。若希望表达更大的直接量,则在直接量的后面加上l或者L,推荐L。
f.浮点类型
• Java语言中用于描述小数数据的类型:float 和 double,推荐double类型
• 其中float类型在内存空间占4个字节,叫做单精度浮点数,可以表示7位 有效数字,范围:-3.403E38~3.403E38。
• 其中double类型在内存空间占8个字节,叫做双精度浮点数,可以表示15 位有效数字,范围:-1.798E308~1.798E308。
• Java程序中直接写出的小数数据叫做直接量,默认为double类型,若希望 表达float类型的直接量,则需要在直接量的后面加上f或者F.
g.布尔类型
• Java语言中用于描述真假信息类型有:boolean,数值只有:true 和 false。
• 布尔类型在内存空间中所占大小没有明确的规定,可以认为是1个字节
h.字符类型
• Java语言中用于描述单个字符的数据类型:char类型。如:'a'、'中'等。
• 其中char类型在内存空间中占2个字节并且没有符号位,表示的范围是:
0 ~ 65535,由于现实生活中很少有数据能够被单个字符描述,因此以后 的开发中更多的使用由多个字符串起来组成的字符串,使用String类型加 以描述,如:“hello”、“奇点”等。
• 计算机的底层只识别0和1组成的二进制序列,对于字符'a'这样的图案来 说不满足该规则,因此该数据无法直接在计算机中存储,但现实生活中 存在这样的图案数据需要计算机存储,为了使得该数据能够存储起来就 可以给该数据指定一个编号,然后将编号存储起来即可,该编号就叫做 ASCII。
• 要求掌握的ASCII有:'0' - 48 'A' - 65 'a' - 97 空格 - 32 换行符 - 10
• Java字符类型采用Unicode字符集编码。Unicode是世界通用的定长字符 集,所有的字符都是16位。
• 要求掌握的转义字符有:\" - " \' - ' \\ - \ \t - 制表符 \n - 换行符
i.基本数据类型的转换
• Java语言中基本数据类型之间的转换方式:自动类型转换和强制类型转换。
• 其中自动类型转换主要指从小类型到大类型之间的转换。
• 其中强制类型转换主要指从大类型到小类型之间的转换,语法格式如下: 目标类型 变量名 = (目标类型)源类型变量名;
• 强转有风险,操作需谨慎!
3、总结
4、代码
5、图片
三、J a v a 语 言 的 运 算 符
1、运算符(重点)
a.算术运算符
• + 表示加法运算符
• - 表示减法运算符
• * 表示乘法运算符
• / 表示除法运算符
• % 表示取模/取余运算符
b.案例题目
• 提示用户输入正整数类型的秒数,拆分秒数后输出x小时x分x秒。
• 如:输入7199,输出1小时59分59秒。
/*编程使用算术运算符实现秒数的拆分*/import java.util.Scanner; public class ArithmeticTimeTest {public static void main(String[] args) {// 1.提示用户输入一个正整数的秒数并使用变量记录System.out.println("请输入一个正整数的秒数:");Scanner sc = new Scanner(System.in);int num = sc.nextInt();// 2.将正整数的秒数拆分为时分秒后并使用变量记录// 3666秒 => 1小时1分钟6秒钟// 3666 / 3600 = 1 小时 3666 % 3600 = 66 / 60 = 1 分钟 3666 % 60 = 6 秒钟 int hour = num / 3600; // 拆分小时数int min = num % 3600 / 60; // 拆分分钟数int sec = num % 60; // 拆分秒数// 3.打印最终的拆分结果System.out.println(num + "秒转换为" + hour + "小时" + min + "分钟" + sec + "秒钟");System.out.println("---------------------------------------------------------------------");// 4.+既可以作为字符串连接符,又可以作为加法运算符// 只要+两边的操作数中有一个操作数是字符串类型,则该+就被当做字符串连接符处理,否则当做加法运算符处理System.out.println(hour + min + sec); // 8System.out.println(hour + min + sec + ""); // 8System.out.println(hour + min + "" + sec); // 26System.out.println(hour + "" + min + sec); // 116System.out.println("" + hour + min + sec); // 116System.out.println("" + (hour + min + sec));// 8}
}
c.字符串连接运算符
• + 可以实现字符串的连接。同时可以实现字符串与其他数据类型“相连”。
d.关系/比较运算符
• > 表示是否大于运算符 >= 表示是否大于等于运算符
• < 表示是否小于运算符 <= 表示是否小于等于运算符
• == 表示是否等于运算符 != 表示是否不等于运算符
• 所有以关系运算符作为最终运算的表达式结果一定是boolean类型。
e.案例题目
• 提示用户输入一个整数,使用关系运算符判断该整数是否为负数,若是 则打印true,若不是则打印false。
/*编程使用关系运算符实现负数的判断*/import java.util.Scanner; public class RelationJudgeTest {public static void main(String[] args) {// 1.提示用户输入一个整数并使用变量记录System.out.println("请输入一个整数:");Scanner sc = new Scanner(System.in);int num = sc.nextInt();// 2.判断该整数是否为负数并打印boolean b1 = num < 0;System.out.println("b1 = " + b1);System.out.println(num < 0);}
}
f.自增减运算符
• ++ 表示自增运算符,用于使得当前变量自身的数值加1的效果
• -- 表示自减运算符,用于使得当前变量自身的数值减1的效果
• 只能用于变量,常数不可以
g.逻辑运算符
• && 表示逻辑与运算符,相当于"并且",同真为真,一假为假。
• || 表示逻辑或运算符,相当于"或者",一真为真,同假为假。
• ! 表示逻辑非运算符,相当于"取反",真为假,假为真。
• 逻辑运算符的操作数均为boolean表达式。
h.逻辑运算符的图解
i.逻辑运算符的短路特性
• 对于逻辑与运算符来说,若第一个表达式为假则结果为假,此时跳过第 二个表达式;
• 对于逻辑或运算符来说,若第一个表达式为真则结果为真,此时跳过第 二个表达式;
j.案例题目
• 提示用户输入一个正整数,使用逻辑运算符判断该正整数是否为三位数, 若是则打印true,否则打印false
/*编程使用逻辑运算符判断三位数*/import java.util.Scanner; public class LogicJudgeTest {public static void main(String[] args) {// 1.提示用户输入一个正整数并使用变量记录System.out.println("请输入一个正整数:");Scanner sc = new Scanner(System.in);int num = sc.nextInt();// 2.使用逻辑运算符判断是否为三位数并打印 >= 100 <= 999 &&//System.out.println(100 <= num <= 999); // 错误: 二元运算符 '<=' 的操作数类型错误// 逻辑运算符主要用于连接多个关系运算符作为最终运算的表达式,用于实现多条件的连接System.out.println(100 <= num && num <= 999);// 使用三目运算符来判断是否为三位数System.out.println(num + ((100 <= num && num <= 999)? "是三位数": "不是三位数"));}
}
k.条件/三目运算符
• 条件表达式? 表达式1: 表达式2
• 判断条件表达式是否成立,若成立则执行表达式1,否则执行表达式2 。
l.案例题目
• 提示用户输入两个整数,使用三目运算符找到最大值并打印出来。
/*编程使用三目运算符查找最大值*/import java.util.Scanner; public class ThreeEyeTest {public static void main(String[] args) {// 1.提示用户输入两个整数并使用变量记录System.out.println("请输入两个整数:");Scanner sc = new Scanner(System.in);int ia = sc.nextInt();int ib = sc.nextInt();// 2.使用三目运算符找到最大值并打印int max = ia > ib? ia: ib;System.out.println("最大值是:" + max);System.out.println("最大值是:" + (ia > ib? ia: ib));}
}
m.赋值运算符
• = 表示赋值运算符,用于将=右边的数据赋值给=左边的变量,覆盖变量 原来的数值。
• 赋值表达式本身也有值,其本身之值即为所赋之值。
• +=、 -=、 *=、 /=、 ...
n.移位运算符(了解)
• << 左移运算符,用于将数据的二进制位向左移动,右边使用0补充
• >> 右移运算符,用于将数据的二进制位向右移动,左边使用符号位补充
• >>> 表示逻辑右移运算符,用于将数据的二进制位向右移动,左边使用0 补充。
o.位运算符(了解)
• & 表示按位与运算符,按照二进制位进行与运算,同1为1,一0为0.
• | 表示按位或运算符,按照二进制位进行或运算,一1为1,同0为0.
• ~ 表示按位取反运算符,按照二进制位进行取反,1为0,0为1.
• ^ 表示按位异或运算符,按照二进制位进行异或运算,同为0,不同为1.
p.运算符的优先级
• ()的优先级极高。
• =的优先级极低。
• 若无法确认优先级,则使用()来确保即可
2、总结答疑
3、代码
/*编程实现算术运算符的使用*/
public class ArithmeticTest {public static void main(String[] args) {// 1.声明两个int类型的变量并初始化//int ia = 6, ib = 2; // 表示声明两个int类型的变量ia和ib,不推荐使用int ia = 6; // 推荐该方式,提高了代码的可读性int ib = 2;System.out.println("ia = " + ia); // ia = 6System.out.println("ib = " + ib); // ib = 2System.out.println("----------------------------------------");// 2.使用上述变量实现算术运算符的使用 + - * / %// 表示声明变量ic来记录ia与ib的和int ic = ia + ib;System.out.println("ic = " + ic); // ic = 8// 其中ia+ib这个整体叫做表达式 ia、ib叫做操作数 +叫做操作符/运算符System.out.println(ia + ib); // 8System.out.println(ia - ib); // 4System.out.println(ia * ib); // 12System.out.println(ia / ib); // 3System.out.println(ia % ib); // 0System.out.println("----------------------------------------");// 3.注意事项// 3.1 当两个整数相除时结果只保留整数部分,丢弃小数部分System.out.println(5 / 2); // 2System.out.println("----------------------------------------");// 3.2 若希望保留小数部分该如何处理?// 处理方式一:使用强制类型转换将其中一个操作数转换为double类型再运算即可System.out.println((double)5 / 2); // 2.5System.out.println(5 / (double)2); // 2.5System.out.println((double)5 / (double)2); // 2.5System.out.println((double)(5 / 2)); // 2.0// 处理方式二:让其中一个操作数乘以1.0即可(推荐)System.out.println(5*1.0 / 2); // 2.5System.out.println(5.0 / 2); // 2.5 ia.0 错误的表示System.out.println("----------------------------------------");// 3.3 0不能作除数//System.out.println(5 / 0); // 编译ok,运行发生java.lang.ArithmeticException(算术异常 记住): / by zeroSystem.out.println(5 / 0.0); // Infinity 无穷System.out.println(0 / 0.0); // NaN Not a Number }
}
/*编程实现自增减运算符的使用*/
public class SelfTest {public static void main(String[] args) {// 1.声明一个int类型的变量并初始化int ia = 10;// 2.打印变量的数值System.out.println("ia = " + ia); // ia = 10System.out.println("---------------------------------------------");// 3.实现自增减运算符的使用// 表示让变量ia自身的数值加1,并覆盖该变量原来的数值 ia++; // ia = ia + 1;System.out.println("ia = " + ia); // ia = 11// 表示让变量ia自身的数值加1,并覆盖该变量原来的数值 ++ia;System.out.println("ia = " + ia); // ia = 12// 表示让变量ia自身的数值减1,并覆盖该变量原来的数值--ia;System.out.println("ia = " + ia); // ia = 11ia--;System.out.println("ia = " + ia); // ia = 10System.out.println("---------------------------------------------");// 4.简单的变换// 其中ia++这个整体叫做表达式 其中ia叫做操作数/变量 也就是ia++和ia表示不同的含义,因此所占的内存空间应该不同// 下面的代码是在打印表达式的结果// 后++表示先让变量ia的数值作为整个表达式的最终结果,然后再让ia变量自身的数值加1System.out.println(ia++); // 10System.out.println("ia = " + ia); // 11// 前++表示先让变量自身的数值加1,然后再让变量的数值作为整个表达式的结果System.out.println(++ia); // 12System.out.println("ia = " + ia); // 12System.out.println("---------------------------------------------");// 5.笔试考点int ib = ia++;System.out.println("ib = " + ib); // 12System.out.println("ia = " + ia); // 13int ic = ++ia;System.out.println("ic = " + ic); // 14System.out.println("ia = " + ia); // 14// 14 + 16System.out.println(ia++ + ++ia); // 30System.out.println("ia = " + ia); // 16}
}
/*编程实现关系运算符的使用*/
public class RelationTest {public static void main(String[] args) {// 1.声明两个int类型的变量并初始化int ia = 5;int ib = 2;// 2.使用变量实现关系运算符的使用并打印结果boolean b1 = ia > ib;System.out.println("b1 = " + b1); // b1 = trueSystem.out.println(ia > ib); // 是否大于 trueSystem.out.println(ia >= ib); // 是否大于等于 大于或者等于 trueSystem.out.println(ia < ib); // 是否小于 falseSystem.out.println(ia <= ib); // 是否小于等于 falseSystem.out.println(ia == ib); // 是否等于 falseSystem.out.println(ia != ib); // 是否不等于 true}
}
/*编程实现移位运算符的使用*/
public class MoveBitTest {public static void main(String[] args) {// 1.声明一个byte类型的变量并初始化byte b1 = 13;// 2.打印变量的数值System.out.println("b1 = " + b1); // b1 = 13System.out.println("---------------------------------------------------");// 3.移位运算符的使用// 13的二进制是:... 0000 1101 => 左移1位的结果是:... 0001 1010 => 换算为十进制整数是:26//byte b2 = b1 << 1; // 错误: 不兼容的类型: 从int转换到byte可能会有损失 自动提升为int类型,也就是32位二进制byte b2 = (byte)(b1 << 1); System.out.println("b2 = " + b2); // 26System.out.println(b1 << 1); // 26 左移1位相当于当前整数的数值*2System.out.println(b1 << 2); // 52 左移2位相当于当前整数的数值*4System.out.println("---------------------------------------------------");// 13的二进制是:... 0000 1101 => 右移1位的结果是:... 0000 0110 => 换算为十进制整数是:6System.out.println(b1 >> 1); // 6 右移1位相当于当前整数的数值/2System.out.println(b1 >> 2); // 3 右移2位相当于当前整数的数值/4System.out.println("---------------------------------------------------");// 逻辑右移 对于非负数来说,逻辑右移和右移的效果一致System.out.println(b1 >>> 2); // 3 }
}
/*编程实现逻辑运算符的使用*/
public class LogicTest {public static void main(String[] args) {// 1.声明两个boolean类型的变量并初始化boolean b1 = true;boolean b2 = false;// 2.打印变量的数值System.out.println("b1 = " + b1); // b1 = trueSystem.out.println("b2 = " + b2); // b2 = falseSystem.out.println("---------------------------------------------");// 3.使用上述变量实现逻辑运算符的使用boolean b3 = b1 && b2;System.out.println("b3 = " + b3); // falseSystem.out.println(b1 && b2); // false 并且System.out.println(b1 || b2); // true 或者System.out.println(!b1); // false 取反System.out.println(!b2); // trueSystem.out.println("---------------------------------------------");// 4.测试一下短路特性int ia = 3;int ib = 5;// 对于逻辑与运算符来说,若第一个条件为假则整个表达式为假,此时跳过第二个表达式不执行boolean b4 = (++ia == 3) && (++ib == 5);System.out.println("b4 = " + b4); // falseSystem.out.println("ia = " + ia); // 4System.out.println("ib = " + ib); // 5// 对于逻辑或运算符来说,若第一个条件为真则整个表达式为真,此时跳过第二个表达式不执行boolean b5 = (++ia == 5) || (++ib == 5);System.out.println("b5 = " + b5); // trueSystem.out.println("ia = " + ia); // 5System.out.println("ib = " + ib); // 5}
}
/*编程实现位运算符的使用*/
public class BitTest {public static void main(String[] args) {// 1.声明两个byte类型的变量并初始化byte b1 = 11;byte b2 = 13;// 2.打印变量的数值System.out.println("b1 = " + b1); // b1 = 11System.out.println("b2 = " + b2); // b2 = 13System.out.println("---------------------------------------------------");// 3.实现位运算符的使用// b1的二进制为: 0000 1011 // b2的二进制为: 0000 1101System.out.println( b1 & b2); // 按位与:同1为1,一0为0 按位与后的二进制为:0000 1001 => 转为十进制是:9System.out.println( b1 | b2); // 按位或:一1为1,同0为0 按位或后的二进制为:0000 1111 => 转为十进制是:15System.out.println( b1 ^ b2); // 按位异或:相同为0,不同为1 按位异或的二进制为:0000 0110 => 转为十进制是:6System.out.println( ~ b1); // 按位取反:1为0,0为1 按位取反的二进制为:1111 0100 // 二进制1111 0100转为十进制 => 先减1: 1111 0011 => 按位取反:0000 1100 => 转为十进制:12 => 添加负号:-12}
}
/*赋值运算符的使用*/
public class AssignTest {public static void main(String[] args) {// 1.声明一个int类型的变量并初始化int ia = 3;// 2.打印变量的数值System.out.println("ia = " + ia); // ia = 3System.out.println("-----------------------------------");// 3.简单赋值运算符的使用// 表示将数据5赋值给变量ia并且覆盖变量ia原来的数值ia = 5;System.out.println("ia = " + ia); // ia = 5// 下面的代码是在打印表达式的结果System.out.println( ia = 5 ); // 5System.out.println("ia = " + ia); // ia = 5int ib = ia = 6;System.out.println("ia = " + ia); // ia = 6System.out.println("ib = " + ib); // ib = 6int ic;ic = ib = ia = 8;System.out.println("ia = " + ia); // ia = 8System.out.println("ib = " + ib); // ib = 8System.out.println("ic = " + ic); // ic = 8System.out.println("-----------------------------------");// 4.复合赋值运算符的使用//ia = ia + 2; 目前推荐使用该方式ia += 2; // 简化写法,从结果上来看是等价的System.out.println("ia = " + ia); // ia = 10System.out.println("-----------------------------------");// 5.笔试考点1byte b1 = 10;System.out.println("b1 = " + b1); // b1 = 10//b1 = b1 + 2; // 错误: 不兼容的类型: 从int转换到byte可能会有损失 byte + int 相加结果还是int类型//b1 = b1 + (byte)2; // 错误: 不兼容的类型: 从int转换到byte可能会有损失 byte + byte 相加结果还是int类型 编译器优化//b1 = (byte)(b1 + 2); // 强制类型转换,将int类型转换为byteb1 += 2; // 真正等价于b1 = (byte)(b1 + 2);System.out.println("b1 = " + b1); // b1 = 12System.out.println("-----------------------------------");// 6.笔试考点2//ia == 2; - 表示判断变量ia的数值是否等于2//2 == ia; - 表示判断2是否等于变量ia的数值,从结果上来说等价,推荐该方式//ia = 2; - 表示将2赋值给变量ia,覆盖变量ia原来的数值//2 = ia; //- 编译报错 错误: 意外的类型}
}
4、图片
四、流程控制语句
1、分支结构(重中之重)
a.分支结构的概念
• 当需要进行条件判断并做出选择时,使用分支结构。
b.if分支结构
• if(条件表达式) { 语句块;
}
c.if分支结构
• 判断条件表达式是否成立
=> 若成立,则执行语句块; => 若不成立,则跳过语句块;
案例题目
• 提示用户输入两个整数,使用if分支结构找到最大值并打印出来
/*编程使用if分支结构查找两个整数中的最大值*/import java.util.Scanner; public class IfMaxTest {public static void main(String[] args) {// 1.提示用户输入两个整数并使用变量记录System.out.println("请输入两个整数:");Scanner sc = new Scanner(System.in);int ia = sc.nextInt();int ib = sc.nextInt();// 2.使用if分支结构找到最大值并打印// 方式一:使用两个if分支结构可以找到最大值/*if(ia >= ib) {System.out.println("最大值是:" + ia);}if(ia < ib) {System.out.println("最大值是:" + ib);}*/// 方式二:假设第一个数为最大值并记录 推荐方式 通用性int max = ia;if(ib > max) {max = ib;}System.out.println("最大值是:" + max);}
}
d.if else分支结构
• if(条件表达式) { 语句块1;
} else {
语句块2; }
• 判断条件表达式是否成立
=> 若成立,则执行语句块1; => 若不成立,则执行语句块2;
案例题目
• 提示用户输入一个整数,使用if else分支结构判断该整数是负数还是非负 数并打印。
• 使用if else分支结构判断该整数是正数、负数还是零
/*编程使用if else分支结构判断是否为负数和非负数*/import java.util.Scanner; public class IfElseJudgeTest {public static void main(String[] args) {// 1.提示用户输入一个整数并使用变量记录System.out.println("请输入一个整数:");Scanner sc = new Scanner(System.in);int num = sc.nextInt();// 2.使用if else分支结构判断负数和非负数并打印if(num < 0) {System.out.println(num + "是负数!");} else {//System.out.println(num + "是非负数!");// 针对目前的非负数再次判断是正数还是零if(num > 0) {System.out.println(num + "是正数!");} else {System.out.println(num + "是零!");}}}
}
e.if else if else分支结构
if else if else分支结构
• if(条件表达式1) {
语句块1; } else if(条件表达式2) {
语句块2; } else {
语句块n; }
• 判断条件表达式1是否成立
=> 若成立,则执行语句块1;
=> 若不成立,则判断条件表达式2是否成立 => 若成立,则执行语句块2; => 若不成立,则执行语句块n;
案例题目
• 根据用户输入的薪水计算个人所得税并打印出来,其中个税起征点为: 5000元,具体规则如下:
package com.lagou.task04;/*编程使用if else if else分支结构来计算个人所得税*/import java.util.Scanner;public class IfSalaryTest {public static void main(String[] args) {// 1.提示用户输入个人的薪水并使用变量记录System.out.println("请输入您的薪水:");Scanner sc = new Scanner(System.in);// 局部变量:作用范围是从声明开始一直方法体结束int salary = sc.nextInt();// 2.使用if else if else分支结构判断薪水所在的范围并计算对应的个人所得税// 个人所得税公式: 本月应纳税所得额 * 对应的税率 - 速算扣除数double salaryPrice = 0.0;if(salary <= 5000) {System.out.println("无需纳税!");}else if(salary <= 8000) {// 块变量:作用范围是从声明开始一直到当前语句块结束//double salaryPrice = (salary - 5000) * 0.03;//salaryPrice = (salary - 5000) * 0.03;salaryPrice = (salary - 5000) * 0.03 - 0;}else if(salary <= 17000) {//salaryPrice = (salary - 8000) * 0.1 + (8000 - 5000) * 0.03;salaryPrice = (salary - 5000) * 0.1 - 210;}else if(salary <= 30000) {//salaryPrice = (salary - 17000) * 0.2 + (17000 - 8000) * 0.1 + (8000 - 5000) * 0.03;salaryPrice = (salary - 5000) * 0.2 - 1410;}// ...// 3.打印最终的计算结果System.out.println("最终的个人所得税是:" + salaryPrice);}
}
案例题目
• 出租车计费方式:由里程钱数和等候时间钱数相加得出。
• 里程数前3公里13元,超过3公里到15公里部分每公里2元,15公里以上部 分每公里3元。
• 等候时间每2分半1元,不足部分不要钱。
• 输入公里数和等候秒数,输出车费。
• 16公里,等候290秒,车费 = 13 +(15-3)*2 + (16-15)*3 + 1 = 41
/*编程使用if分支结构实现出租车计费系统的实现*/import java.util.Scanner; public class IfTaxiTest {public static void main(String[] args) {// 1.提示用户输入公里数和等待的秒数并使用变量记录System.out.println("请输入公里数和等待的秒数:");Scanner sc = new Scanner(System.in);int km = sc.nextInt();int sec = sc.nextInt();// 2.根据公里数计算对应的里程费并使用变量记录int kmPrice = 0;if(km <= 3) {kmPrice = 13;} else if(km <= 15) {kmPrice = 13 + (km - 3) * 2;} else {kmPrice = 13 + (15 - 3) * 2 + (km - 15) * 3;}// 3.根据等待的秒数来计算对应的等待费并使用变量记录int secPrice = sec / 150;// 4.计算总费用并打印int sumPrice = kmPrice + secPrice;System.out.println("本次出租车的总费用是:" + sumPrice);}
}
f. switch case分支结构
• switch(变量/表达式) {
case 字面值1: 语句块1; break; case 字面值2: 语句块2; break;
...
default:语句块n; }
• 计算变量/表达式的数值 => 判断是否匹配字面值1
=> 若匹配,则执行语句块1 => 执行break跳出当前结构 => 若不匹配,则判断是否匹配字面值2
=> 若匹配,则执行语句块2 => 执行break跳出当前结构 => 若不匹配,则执行语句块n
• switch()中支持的数据类型有:byte、short、char以及int类型,从jdk1.5 开始支持枚举类型,从jdk1.7开始支持String类型。
案例题目
• 使用switch case分支结构模拟以下菜单效果。
/*编程使用switch case分支结构来模拟菜单的效果*/import java.util.Scanner; public class SwitchMenuTest {public static void main(String[] args) {// 1.绘制字符界面System.out.println(" 欢迎来到拉勾教育");System.out.println("-------------------------------------");System.out.print(" [1]学员系统 ");System.out.println("[2]管理员系统");System.out.println(" [0]退出系统");System.out.println("-------------------------------------");System.out.println("请选择要进入的系统:");Scanner sc = new Scanner(System.in);int choose = sc.nextInt();// 2.使用switch case分支结构来模拟用户的选择并给出提示switch(choose) {case 1: System.out.println("正在进入学员系统..."); break;case 2: System.out.println("正在进入管理员系统..."); break;case 0: System.out.println("谢谢使用,下次再见!"); break;default: System.out.println("输入错误,请重新选择!");}}
}
2、循环结构
a.循环结构的概念
• 在Java程序中若希望重复执行一段代码时,就需要使用循环结构。
• 任何复杂的程序逻辑都可以通过顺序、分支、循环三种程序结构实现。
b.for循环
for循环
• for(初始化表达式; 条件表达式; 修改初始值表达式) {
循环体; }
• 执行初始化表达式 => 判断条件表达式是否成立
=> 成立则执行循环体 => 修改初始值表达式 => 判断条件是否成立 => 若不成立,则循环结束
案例题目
/*
编程使用for循环实现1 ~ 100之间所有奇数的打印
*/
/*编程使用for循环实现1 ~ 100之间所有奇数的打印*/
public class ForNumTest {public static void main(String[] args) {// 1.使用for循环打印1 ~ 100之间的所有奇数// 方式一:根据奇数的概念进行打印for(int i = 1; i <= 100; i++) {// 若当前i的数值是奇数时则打印,否则不打印 奇数就是不能被2整除的数,也就是对2取余的结果不为0if(i % 2 != 0) {System.out.println("i = " + i);}}System.out.println("---------------------------------------------------");// 方式二:根据等差数列的概念来打印 每两个数据之间相差2for(int i = 1; i <= 100; i += 2) {System.out.println("i = " + i);}System.out.println("---------------------------------------------------");// 方式三:根据通项公式的规则来打印 2*i-1for(int i = 1; i <= 50; i++) {System.out.println("i = " + (2 * i - 1));}}
}
• 使用for循环实现累加:1+2+...+10000=?最后打印出来。
• 使用for循环实现累加:1+2+...+10000=?最后打印出来。
/*编程使用for循环实现1 ~ 10000之间所有整数的累加和*/
public class ForSumTest {public static void main(String[] args) {// 2.声明一个变量负责记录累加的结果int sum = 0;// 1.使用for循环打印1 ~ 10000之间的所有整数for(int i = 1; i <= 10000; i++) {// 打印后不换行//System.out.print(i + " ");// 将所有i的取值都累加到变量sum中sum += i; // sum = sum + i;}// 专门用于换行//System.out.println();// 3.打印最终的累加结果System.out.println("sum = " + sum);}
}
• 使用for循环打印三位数中所有水仙花数。
• 所谓“水仙花数”即一个整数满足其值等于各个数位的立方和。
• 如:153是一个水仙花数,因为153=1^3+5^3+3^3。
/*编程使用for循环打印三位数中的所有水仙花数*/
public class ForWaterTest {public static void main(String[] args) {// 1.使用for循环打印所有的三位数for(int i = 100; i <= 999; i++) {// 3.拆分三位数中的各个数位上的数字// 123 / 100 = 1; 123 % 100 => 23 / 10 = 2; 123 % 10 = 3;int ia = i / 100; // 拆分百位数int ib = i % 100 / 10; // 拆分十位数int ic = i % 10; // 拆分个位数// 2.针对每个三位数都要判断该数是否为水仙花数,若是则打印,否则不打印// 判断该数是否等于各个数位的立方和if((ia*ia*ia + ib*ib*ib + ic*ic*ic) == i) {System.out.println("i = " + i);}}}
}
c.continue关键字
• continue语句用在循环体中,用于结束本次循环而开始下一次循环。
案例题目
• 使用for循环打印1 ~ 20之间的所有整数,若遇到5的倍数则跳过不打印。
/*编程实现continue关键字的使用*/
public class ForContinueTest {public static void main(String[] args) {// 1.使用for循环打印1 ~ 20之间的所有整数for(int i = 1; i <= 20; i++) {// 若遇到5的倍数则跳过不打印该数,转而继续打印下一个数if(0 == i % 5) {continue; // 表示提前结束本次循环,继续下一次循环,也就是奔向了i++}System.out.println("i = " + i);}}
}
d.break关键字
• break用于退出当前语句块,break用在循环体中用于退出循环。
• for(;;) - 这种没有循环条件的循环叫做 无限循环,俗称“死循环”。
案例题目
• 不断地提示用户输入聊天内容并输出,直到用户输入”bye”结束聊天
/*编程使用for循环和break关键字来模拟聊天的过程*/import java.util.Scanner; public class ForBreakTest {public static void main(String[] args) {// 5.声明一个boolean类型的变量作为发送方的标志boolean flag = true;// 4.使用无限循环来模拟不断地聊天for(;;) {// 1.提示用户输入要发送的聊天内容并使用变量记录System.out.println("请" + (flag? "张三": "李四") +"输入要发送的聊天内容:");Scanner sc = new Scanner(System.in);String str = sc.next();// 2.判断用户输入的内容是否为"bye",若是则聊天结束if("bye".equals(str)) {System.out.println("聊天结束!");break; // 用于跳出当前循环}// 3.若不是则打印用户输入的聊天内容//else {//System.out.println("聊天内容是:" + str);//}System.out.println((flag? "张三说:": "李四说:") + str + "\n\n\n");flag = !flag;}// ...}
}
• 猜数字游戏
• 随机生成数字n(1-100), 等待用户输入猜测数据, 根据用户的输入比较输出 猜大了,猜小了,猜对了, 如果用户猜对了就结束游戏
/*编程使用for循环实现猜数字游戏*/import java.util.Random;
import java.util.Scanner;public class ForGuessTest {public static void main(String[] args) {// 1.随机生成1 ~ 100之间的整数并使用变量记录Random ra = new Random();int temp = ra.nextInt(100) + 1;//System.out.println("temp = " + temp);// 4.声明一个int类型的变量来统计用户猜测的次数int cnt = 0;for(;;) {// 2.提示用户输入1 ~ 100之间猜测的整数并使用变量记录System.out.println("请输入1 ~ 100之间猜测的整数:");Scanner sc = new Scanner(System.in);int num = sc.nextInt();cnt++;// 3.使用用户输入的整数与随机数之间比较大小并给出对应的提示if(num > temp) {System.out.println("猜大了,再小一点吧!");} else if(num < temp) {System.out.println("猜小了,再大一点吧!");} else {System.out.println("恭喜您猜对了,游戏结束!");break;}}if(1 == cnt) {System.out.println("你果然是个大咖!");} else if(cnt <= 6) {System.out.println("水平不错,继续加油哦!");} else {System.out.println("你还可以多玩几次游戏!");}}
}
e.双重for循环
• for(初始化表达式1; 条件表达式2; 修改初始值表达式3) { for(初始化表达式4; 条件表达式5; 修改初始值表达式6) {
循环体; }
}
执行表达式1 => 判断表达式2是否成立
=> 若成立,则执行表达式4 => 判断表达式5是否成立
=> 若成立,则执行循环体 => 执行表达式6 => 表达式5是否成立 => 若不成立,则内层循环结束 => 表达式3 => 表达式2是否成立
=> 若不成立,则外层循环结束
双重for循环的特点
• 外层循环用于控制打印的行数,内层循环用于控制打印的列数,外层循 环改一下,内层循环从头到尾跑一圈。
• 在以后的开发中若需要打印多行多列时,需要使用双重循环。
• 多重循环不宜嵌套太多层,否则效率很低。一般到三重循环即可,最常 见的就是双重循环。
案例题目
• 使用双重for循环分别打印以下图案
/*编程使用双重for循环打印星星图案*/
public class ForForStarTest {public static void main(String[] args) {// 1.打印第一个星星图案// 外层循环主要用于控制打印的行数for(int i = 1; i <= 5; i++) {// 内层循环主要用于控制打印的列数for(int j = 1; j <= 5; j++) {System.out.print("*");}System.out.println();}System.out.println("--------------------------------------------");// 2.打印第二个星星图案// 外层循环主要用于控制打印的行数for(int i = 1; i <= 5; i++) {// 内层循环主要用于控制打印的列数 也就是当前行的列数与当前行的行数是相等关系for(int j = 1; j <= i; j++) {System.out.print("*");}System.out.println();}System.out.println("--------------------------------------------");// 3.打印第三个星星图案// 外层循环主要用于控制打印的行数for(int i = 1; i <= 5; i++) {// 内层循环主要用于控制打印的列数 也就是当前行的列数与当前行的行数相加为6的关系for(int j = 1; j <= 6-i; j++) {System.out.print("*");}System.out.println();}System.out.println("--------------------------------------------");// 4.打印第四个星星图案// 外层循环主要用于控制打印的行数for(int i = 1; i <= 5; i++) {// 控制空格的个数for(int j = 1; j <= 5-i; j++) {System.out.print(" ");}// 内层循环主要用于控制打印的列数 也就是当前行的列数与当前行的行数为 2*i-1 的关系for(int j = 1; j <= 2*i-1; j++) {System.out.print("*");}System.out.println();}}
}
• 使用双重for循环打印九九乘法表
/*使用双重for循环打印九九乘法表*/
public class ForForTableTest {public static void main(String[] args) {// 1.使用外层for循环控制打印的行数,一共9行outer:for(int i = 1; i <= 9; i++) {// 2.使用内层for循环控制打印的列数,最多9列,规律是:与当前行所在的行数相等for(int j = 1; j <= i; j++) {// 3.使用两个循环变量来拼接等式System.out.print(j + "*" + i + "=" + j*i + " ");// 4.当打印完毕6*6 = 36后结束整个打印if(6 == j) {//break; // 主要用于跳出循环,但该关键字只能跳出当前所在的循环break outer; // 表示可以跳出外层for循环}}System.out.println();}}
}
f.break关键字跳出多层循环
• 在嵌套的循环结构中,break用于退出所在循环体。
• 如果要退出外层循环体,需要使用标号的方式。
for (...) {
for(...) {
break;
}
}
outer: for (...) {
for(...) {
break outer;
}
}
案例题目
• 使用双重for循环打印2~100之间的所有素数。
• 当一个数只能被1和它本身整除时,这个数就叫做素数或质数。
/*编程使用双重for循环打印2 ~ 100之间的所有素数*/
public class ForForPrimeTest {public static void main(String[] args) {// 1.使用for循环打印2 ~ 100之间的所有整数for(int i = 2; i <= 100; i++) {// 3.声明一个boolean类型的变量作为是否为素数的标记boolean flag = true;// 2.针对每一个当前的整数都要判断是否为素数,若是素数则打印,否则不打印// 判断一个数是否为素数的方法是:若该数不能被2到它本身-1之间的所有整数整除时,则证明该数是素数// 使用内层for循环用于控制2到该数自身-1之间的范围//for(int j = 2; j < i; j++) {// 只需要判断2到该数的平方根即可,因为随着除数的增大商必然减小,会造成重复的判断for(int j = 2; j <= Math.sqrt(i); j++) {// 使用当前数除以该循环中的每个数据并判断是否可以整除,只要找到一个可以整除的数据,则证明该数不是素数if(0 == i % j) {flag = false;break; // 跳出当前所在的内层循环,也就是不需要再继续除以下一个整数}}// 只可以打印素数if(flag) {System.out.println("i = " + i);}}}
}
g.while循环
• while(条件表达式) {
循环体;
}
• 判断条件表达式是否成立
=> 若成立,则执行循环体 => 判断条件表达式是否成立 => 若不成立,则循环结束
案例题目
• 使用while循环计算调和数列的和并打印,即: 1/1 + 1/2 + ... + 1/n。
/*编程使用while循环实现调和数列的累加和并打印*/import java.util.Scanner; public class WhileSumTest {public static void main(String[] args) {// 1.提示用户输入一个整数并使用变量记录System.out.println("请输入一个整数:");Scanner sc = new Scanner(System.in);int num = sc.nextInt();// 2.使用while循环计算调和数列的和并使用变量记录double sum = 0.0;/*for(int i = 1; i <= num; i++) {sum += 1.0/i;}*/int i = 1;while(i <= num) {sum += 1.0/i;i++;}// 3.打印最终的计算结果System.out.println("最终的计算结果是:" + sum);}
}
h.while循环和for循环比较
• while循环和for循环完全可以互换,当然推荐使用for循环。
• while循环更适合于明确循环条件但不明确循环次数的场合中。
• for循环更适合于明确循环次数或范围的场合中。
• while(true) 等价于 for(;;) 都表示无限循环。
案例题目
• 提示用户输入一个任意位数的正整数然后反向输出
/*编程使用while循环实现任意正整数的反向输出*/import java.util.Scanner; public class WhileReverseTest {public static void main(String[] args) {// 1.提示用户输入一个正整数并使用变量记录 123System.out.println("请输入一个正整数:");Scanner sc = new Scanner(System.in);int num = sc.nextInt();// 2.使用while循环进行拆分并打印//while(num > 0) {//System.out.print(num % 10); // 拆分个位数//num /= 10; // 丢弃个位数//}// 2.使用while循环拆分整数中的每个数字并记录到变量中int res = 0;int temp = num; // 指定变量作为num的替身while(temp > 0) {res = res*10 + temp % 10; // 3 32 321temp /= 10; // 12 1 0}// 3.打印逆序后的结果System.out.println(num + "逆序后的结果是:" + res);}
}
i.do while循环(熟悉)
• do {
循环体;
} while(条件表达式);
• 执行循环体 => 判断条件表达式是否成立
=> 若成立,则执行循环体 => 判断条件表达式是否成立 => 若不成立,则循环结束
do while循环
• do-while循环主要用于至少执行一次循环体的场合中。
案例题目
• 使用do while循环来模拟学习任务是否合格的检查, 如果合格则停止, 否则就重新完成学习任务。
/*编程使用do while循环来模拟学习效果的检查*/import java.util.Scanner; public class DoWhileCheckTest {public static void main(String[] args) throws Exception {String msg = null; // 空 do {System.out.println("正在疯狂学习中...");Thread.sleep(5000); // 模拟5秒钟System.out.println("是否合格?(y/n)");Scanner sc = new Scanner(System.in);msg = sc.next();} while(!"y".equals(msg));System.out.println("恭喜任务合格!");System.out.println("-------------------------------------------------------------");// 典故: 十动然拒 笔试考点:有没有分号int i = 1;while(i <= 10000) {; // 空语句,啥也不干,可以用于延时}{System.out.println("I Love You !");i++;}}
}
3、总结和答疑
4、代码
5、图片
五、数组的概念以及应用
1、一维数组
a.一维数组的基本概念
• 当需要在Java程序中记录单个数据内容时,则声明一个变量即可。
• 当需要在Java程序中记录多个类型相同的数据内容时,则声明一个一维数 组即可,一维数组本质上就是在内存空间中申请一段连续的存储单元。
• 数组是相同数据类型的多个元素的容器,元素按线性顺序排列,在Java语 言中体现为一种引用数据类型。
b.一维数组的声明方式
• 数据类型[] 数组名称 = new 数据类型[数组的长度];
• 调用数组的length属性可以获取数组的长度:
• 可以通过下标的方式访问数组中的每一个元素。需要注意的是:数组的 下标从0开始,对于长度为n的数组,下标的范围是0~n-1。
d.一维数组的初始化方式
• 基本类型的数组(数据元素为基本类型)创建后,其元素的初始值:byte、 short、char、int、long为0;float和double为0.0;boolean为false。
• 可以在数组声明的同时进行初始化,具体如下: 数据类型[] 数组名称 = {初始值1, 初始值2, ...};
e.内存结构之栈
• 栈用于存放程序运行过程当中所有的局部变量。一个运行的Java程序从开 始到结束会有多次变量的声明
f.内存结构之堆区
• JVM会在其内存空间中开辟一个称为“堆”的存储空间,这部分空间用于存 储使用new关键字创建的数组和对象。
案例题目
• 声明一个长度为5元素类型为int类型的一维数组,打印数组中所有元素值;
• 使用元素11、22、33、44分别对数组中前四个元素赋值后再次打印;
• 将元素55插入到下标为0的位置,原有元素向后移动,再打印所有元素值;
• 将元素55从数组中删除,删除方式为后续元素向前移动,最后位置置为0 并打印;
• 查找数组中是否存在元素22,若存在则修改为220后再次打印所有元素;
/*编程实现一维数组的增删改查操作
*/
public class ArrayOpTest {public static void main(String[] args) {// 1.声明一个长度为5元素类型为int类型的一维数组int[] arr = new int[5];// 打印数组中所有元素的数值System.out.print("数组中的元素有:");for(int i = 0; i < arr.length; i++) {System.out.print(arr[i] + " "); // 全是默认值0}System.out.println();System.out.println("-------------------------------------------------");// 2.将数据11 22 33 44依次对数组中前四个元素赋值/*arr[0] = 11;arr[1] = 22;arr[2] = 33;arr[3] = 44;*/for(int i = 0; i < arr.length-1; i++) {arr[i] = (i+1)*11;}// 打印数组中所有元素的数值System.out.print("数组中的元素有:");for(int i = 0; i < arr.length; i++) {System.out.print(arr[i] + " "); // 11 22 33 44 0}System.out.println();System.out.println("-------------------------------------------------");// 3.将数据55插入到下标为0的位置,原有元素向后移动/*arr[4] = arr[3];arr[3] = arr[2];arr[2] = arr[1];arr[1] = arr[0];arr[0] = 55;*/for(int i = arr.length-1; i > 0; i--) {arr[i] = arr[i-1];}arr[0] = 55;// 打印数组中所有元素的数值System.out.print("数组中的元素有:");for(int i = 0; i < arr.length; i++) {System.out.print(arr[i] + " "); // 55 11 22 33 44}System.out.println();System.out.println("-------------------------------------------------");// 4.将数据55从数组中删除,删除方式为后续元素向前移动,最后一个位置置为0/*arr[0] = arr[1];arr[1] = arr[2];arr[2] = arr[3];arr[3] = arr[4];*/for(int i = 0; i < arr.length-1; i++) {arr[i] = arr[i+1];}arr[4] = 0;// 打印数组中所有元素的数值System.out.print("数组中的元素有:");for(int i = 0; i < arr.length; i++) {System.out.print(arr[i] + " "); // 11 22 33 44 0}System.out.println();System.out.println("-------------------------------------------------");// 5.查找数组中是否有元素22,若有则修改为220for(int i = 0; i < arr.length; i++) {if(22 == arr[i]) {arr[i] = 220;}}// 打印数组中所有元素的数值System.out.print("数组中的元素有:");for(int i = 0; i < arr.length; i++) {System.out.print(arr[i] + " "); // 11 220 33 44 0}System.out.println();}
}
g.数组的优缺点
数组的优缺点
• 可以直接通过下标(或索引)的方式访问指定位置的元素,速度很快。
• 数组要求所有元素的类型相同。
• 数组要求内存空间连续,并且长度一旦确定就不能修改。
• 增加和删除元素时可能移动大量元素,效率低。
案例题目
• 声明一个初始值为11 22 33 44 55的一维数组并打印所有元素
• 声明一个长度为3元素类型为int类型的一维数组并打印所有元素
• 实现将第一个数组中间3个元素赋值到第二个数组中
• 再次打印第二个数组中的所有元素
/*编程实现数组之间元素的拷贝*/
public class ArrayCopyTest {public static void main(String[] args) {// 1.声明一个初始值为11、22、33、44、55的一维数组int[] arr = {11, 22, 33, 44, 55};// 打印数组中的所有元素System.out.print("第一个数组中的元素有:");for(int i = 0; i < arr.length; i++) {System.out.print(arr[i] + " "); // 11 22 33 44 55}System.out.println();System.out.println("----------------------------------------------------------");// 2.声明一个长度为3元素类型为int类型的一维数组int[] brr = new int[3];// 打印数组中的所有元素System.out.print("第二个数组中的元素有:");for(int i = 0; i < brr.length; i++) {System.out.print(brr[i] + " "); // 0 0 0}System.out.println();System.out.println("----------------------------------------------------------");// 3.将第一个数组中的中间3个元素赋值到第二个数组中/*brr[0] = arr[1];brr[1] = arr[2];brr[2] = arr[3];*//*for(int i = 0; i < brr.length; i++) {brr[i] = arr[i+1];}*/// 可以直接使用Java官方提供的拷贝功能// 表示将数组arr中下标从1开始的3个元素拷贝到数组brr中下标从0开始的位置System.arraycopy(arr, 1, brr, 0, 3);// 打印第二个数组中的所有元素System.out.print("第二个数组中的元素有:");for(int i = 0; i < brr.length; i++) {System.out.print(brr[i] + " "); // 22 33 44}System.out.println();System.out.println("----------------------------------------------------------");// 4.笔试考点// 表示将变量arr的数值赋值给变量brr,覆盖变量brr中原来的数值// 数组名arr的内存空间中存放的是数据在堆区中的内存地址信息,赋值后让brr变量中存放了arr所指向堆区的内存地址// 也就是让brr和arr指向了同一块堆区空间,有本质上就是改变指向而已brr = arr;// 打印第二个数组中的所有元素System.out.print("第二个数组中的元素有:");for(int i = 0; i < brr.length; i++) {System.out.print(brr[i] + " "); // 22 33 44}System.out.println(); }
}
案例题目
• 编程统计用户输入任意一个正整数中每个数字出现次数的统计并打印。
• 如:123123 => 1出现2次,2出现2次,3出现2次
/*编程使用数组实现正整数中每个数字出现次数的统计*/import java.util.Scanner; public class ArrayCountTest {public static void main(String[] args) {// 1.提示用户输入一个正整数并使用变量记录System.out.println("请输入一个正整数:");Scanner sc = new Scanner(System.in);int num = sc.nextInt();// 2.准备一个长度为10元素类型int类型的一维数组,默认值为0int[] arr = new int[10];// 3.拆分正整数中的每个数字并统计到一维数组中int temp = num;while(temp > 0) {arr[temp%10]++;temp /= 10;}// 4.打印最终的统计结果for(int i = 0; i < arr.length; i++) {if(arr[i] > 0) {System.out.println("数字" + i + "出现了" + arr[i] + "次!");}}}
}
案例题目
• 提示用户输入学生的人数以及每个学生的考试成绩并打印出来。
• 计算该班级的总分和平均分并打印出来。
/*编程使用数组来记录学生的考试成绩并打印*/import java.util.Scanner;
import java.util.Arrays;public class ArrayScoreTest {public static void main(String[] args) {// 1.提示用户输入学生的人数并使用变量记录System.out.println("请输入学生的人数:");Scanner sc = new Scanner(System.in);int num = sc.nextInt();// 2.根据学生的人数来声明对应长度的数组负责记录学生的考试成绩// 变长数组 : 主要指变量可以作为数组的长度,但绝不是数组的长度可以发生改变int[] scores = new int[num];// 3.提示用户输入每个学生的考试成绩并记录一维数组中for(int i = 0; i < num; i++) {System.out.println("请输入第" + (i+1) + "个学生的考试成绩:");scores[i] = sc.nextInt();}// 4.打印所有学生的考试成绩System.out.print("本班学生的考试成绩分别是:");for(int i = 0; i < scores.length; i++) {System.out.print(scores[i] + " ");}System.out.println();System.out.println("----------------------------------------------");// 5.计算本班级学生的总分以及平均分并使用变量记录int sum = 0;for(int i = 0; i < scores.length; i++) {sum += scores[i];}double avg = sum*1.0 / num;// 打印最终的计算结果System.out.println("本班级学生的总分是:" + sum + ",平均分是:" + avg);System.out.println("----------------------------------------------");// 6.查找本班所有学生考试成绩中的最低分和最高分并打印出来System.out.println("原始的考试成绩是:" + Arrays.toString(scores));// 调用工具类中的排序方法对所有考试成绩进行从小到大的排序Arrays.sort(scores);System.out.println("排序后的考试成绩是:" + Arrays.toString(scores));System.out.println("最低分是:" + scores[0] + ",最高分是:" + scores[num-1]);System.out.println("----------------------------------------------");// 从数组中查找指定元素所在的下标位置System.out.println("59分在数组中的下标位置是:" + Arrays.binarySearch(scores, 59));System.out.println("60分在数组中的下标位置是:" + Arrays.binarySearch(scores, 60));}
}
h.数组工具类的概念
• java.util.Arrays类可以实现对数组中元素的遍历、查找、排序等操作。
i.数组工具类的常用方法
2、二维数组
a.二维数组的概念
二维数组本质上就是由多个一维数组摞在一起组成的数组,二维数组中 的每个元素都是一维数组,而一维数组中的每个元素才是数据内容。
b.二维数组的声明和初始化方式
• 数据类型[][] 数组名称 = new 数据类型[行数][列数];
• 数据类型[][] 数组名称 = {{元素1, 元素2,...}, ...};
案例题目
• 根据用户输入的行数n输出对应行数的杨辉三角,具体如下:
/*编程使用二维数组来实现杨辉三角的生成和遍历*/import java.util.Scanner; public class ArrayArrayTriangleTest {public static void main(String[] args) {// 1.提示用户输入一个行数并使用变量记录System.out.println("请输入一个行数:");Scanner sc = new Scanner(System.in);int num = sc.nextInt();// 2.根据用户输入的行数来声明对应的二维数组int[][] arr = new int[num][];// 3.针对二维数组中的每个元素进行初始化,使用双重for循环// 使用外层for循环控制二维数组的行下标for(int i = 0; i < num; i++) {// 针对二维数组中的每一行进行内存空间的申请arr[i] = new int[i+1];// 使用内层for循环控制二维数组的列下标for(int j = 0; j <= i; j++) {// 当列下标为0或者列下标与当前行的行下标相等时,则对应位置的元素就是1if(0 == j || i == j) {arr[i][j] = 1;} else {// 否则对应位置的元素就是上一行当前列的元素加上上一行前一列的元素arr[i][j] = arr[i-1][j] + arr[i-1][j-1];}}}// 4.打印最终生成的结果for(int i = 0; i < num; i++) {for(int j = 0; j <= i; j++) {System.out.print(arr[i][j] + " ");}System.out.println();}}
}
/*编程实现二维数组的声明和使用*/
public class ArrayArrayTest {public static void main(String[] args) {// 1.声明一个具有2行3列元素类型为int类型的二维数组int[][] arr1 = new int[2][3];// 打印数组中的每个元素// 使用外层for循环控制打印的行数for(int i = 0; i < arr1.length; i++) {// 使用内层for循环控制打印的列数for(int j = 0; j < arr1[i].length; j++) {System.out.print(arr1[i][j] + " "); // 全是0}System.out.println();}System.out.println("--------------------------------------------------");// 2.实现二维数组中元素的赋值int cnt = 1;// 使用外层for循环控制打印的行数for(int i = 0; i < arr1.length; i++) {// 使用内层for循环控制打印的列数for(int j = 0; j < arr1[i].length; j++) {arr1[i][j] = cnt++;}}// 使用外层for循环控制打印的行数for(int i = 0; i < arr1.length; i++) {// 使用内层for循环控制打印的列数for(int j = 0; j < arr1[i].length; j++) {System.out.print(arr1[i][j] + " "); // 1 2 3 4 5 6}System.out.println();}System.out.println("--------------------------------------------------");// 3.二维数组元素的初始化操作int[][] arr2 = {{11, 22, 33, 44}, {55, 66, 77, 88}};// 使用外层for循环控制打印的行数for(int i = 0; i < arr2.length; i++) {// 使用内层for循环控制打印的列数for(int j = 0; j < arr2[i].length; j++) {System.out.print(arr2[i][j] + " "); // 11 22 33 44 55 66 77 88}System.out.println();}System.out.println("--------------------------------------------------");// 4.考点int[][] arr3 = new int[3][];arr3[0] = new int[3];arr3[1] = new int[4];arr3[2] = new int[5];}
}
3、总结和答疑
4、代码
/*编程实现一维数组的声明和使用*/
public class ArrayTest {public static void main(String[] args) {// 1.声明一个长度为2元素类型为int类型的一维数组// 数据类型[] 数组名称 = new 数据类型[数组的长度];//int arr1[] = new int[2]; // 两种方式从结果上来说是一样的,不推荐使用//int num = 2; // 声明一个初始值为2的变量 int[] arr1 = new int[2]; // 推荐该方式,更容易与变量的声明区分,提高了代码的可读性 动态方式// 2.打印一维数组的长度以及每个元素的数值System.out.println("数组的长度是:" + arr1.length); // 2 下标从0 ~ 1System.out.println("下标为0的元素是:" + arr1[0]); // 0 默认值System.out.println("下标为1的元素是:" + arr1[1]); // 0 //System.out.println("下标为2的元素是:" + arr1[2]); // 编译ok,运行发生ArrayIndexOutOfBoundsException数组下标越界异常System.out.println("------------------------------------------------");// 3.使用for循环打印数组中的所有元素for(int i = 0; i < arr1.length; i++) {System.out.println("下标为" + i + "的元素是:" + arr1[i]); // 全是0}// 7.直接通过数组名来打印数组中的所有元素System.out.println("arr1 = " + arr1); // 地址信息System.out.println("------------------------------------------------");// 4.声明一个长度为5元素类型为double类型的一维数组double[] arr2 = new double[5];// 打印数组中每个元素值for(int i = 0; i < arr2.length; i++) {System.out.println("下标为" + i + "的元素是:" + arr2[i]); // 全是0.0 }System.out.println("------------------------------------------------");// 5.声明数组的同时就对数组中的元素进行初始化 静态方式的简化版char[] arr3 = {'a', 'b', 'c', 'd'};// 打印数组中的每个元素值for(int i = 0; i < arr3.length; i++) {System.out.println("下标为" + i + "的元素是:" + arr3[i]); // a b c d}System.out.println("------------------------------------------------");// 6.特殊的写法 静态方式boolean[] arr4 = new boolean[]{true, true, false, false};// 打印数组中的每个元素值for(int i = 0; i < arr4.length; i++) {System.out.println("下标为" + i + "的元素是:" + arr4[i]); // true true false false}}
}
/*编程实现数组工具类的使用*/import java.util.Arrays; public class ArraysTest {public static void main(String[] args) {// 1.声明一个初始值为10、20、30、40、50的一维数组int[] arr1 = {10, 20, 30, 40, 50};// 2.使用原始方式打印数组中的所有元素,要求打印格式为:[10, 20, 30, 40, 50]System.out.print("第一个数组中的元素有:[");for(int i = 0; i < arr1.length; i++) {// 当打印的元素是最后一个元素时,则直接打印元素本身即可if(arr1.length-1 == i) {System.out.print(arr1[i]);} else {// 否则打印元素后打印逗号加空格System.out.print(arr1[i] + ", ");}}System.out.println("]");System.out.println("---------------------------------------------------");// 3.使用数组工具类实现数组中所有元素的打印System.out.println("第一个数组中的元素有:" + Arrays.toString(arr1)); // [10, 20, 30, 40, 50]System.out.println("---------------------------------------------------");// 4.声明一个长度为5元素类型为int类型的一维数组int[] arr2 = new int[5];System.out.println("第二个数组中的元素有:" + Arrays.toString(arr2)); // [0, 0, 0, 0, 0]// 使用数组工具类中的fill方法实现数组中元素的填充并打印// 表示使用10来填充数组arr中的每个元素,也就是给数组中每个元素赋值为10Arrays.fill(arr2, 10);System.out.println("第二个数组中的元素有:" + Arrays.toString(arr2)); // [10, 10, 10, 10, 10]System.out.println("---------------------------------------------------");// 5.声明一个长度为5元素类型为int类型的一维数组并初始化int[] arr3 = new int[5];Arrays.fill(arr3, 10);System.out.println("第三个数组中的元素有:" + Arrays.toString(arr3)); // [10, 10, 10, 10, 10]// 判断该数组是否与上述数组相等并打印,若相同则打印true,否则打印falseSystem.out.println(Arrays.equals(arr2, arr3)); // true// 修改数组3中的元素值arr3[4] = 20;System.out.println("第三个数组中的元素有:" + Arrays.toString(arr3)); // [10, 10, 10, 10, 20]System.out.println(Arrays.equals(arr2, arr3)); // false 要求内容要相同arr2[3] = 20;System.out.println("第二个数组中的元素有:" + Arrays.toString(arr2)); // [10, 10, 10, 20, 10]System.out.println(Arrays.equals(arr2, arr3)); // false 要求顺序要相同}
}
5、图片