## 对于Java的笔记自我总结
学习了一年多Java,感觉学的太慢了真的,所以想现在系统学习一遍在,同时认真总结一份笔记,希望帮助别人,也夯实基础,写的不好的地方请多多谅解。
这是我根据自学的课程进行的笔记总结,会长久更新,若有不足请各位多提意见。
任务一:初识计算机和Java语言:
计算机俗称电脑,相信大家都不陌生,是用于高级计算,使用广泛的设备。主要有软件和硬件组成。计算机硬件是客观存在的各种计算机相关设备,而计算机的软件是用于控制各种硬件设备完成各种功能。硬件通俗来说是:看得见,摸得着。软件:看得见,摸不着。大家都用过,不要我多说什么了相信。
常见的主要硬件
• 计算机硬件(Computer Hardware)主要包括:中央处理器(CPU)、内存、硬盘、输入输出设备、主板、机箱和电源等辅助设备。
CPU:类似人的大脑,用于计算机的计算。解释电脑指令和处理计算机的数据。
输入输出设备:键盘和显示器。
内存:容量小,CPU可以直接访问内存的数据,效率高,但是不能永久存储,一旦断电就会失去数据。
硬盘:CPU不能直接访问,但是容量大,可以永久存储。
科普小知识:
• 1Tb = 1024Gb
1Gb = 1024Mb
1Mb = 1024Kb
1Kb = 1024Byte (字节)
1Byte = 8Bit (二进制位)
常见的主要软件
• 计算机软件(Computer Software)可分为系统软件和应用软件,系统软件
就是操作系统,是其他软件的基础。
• 主流的操作系统有:Windows/Unix/Linux/IOS/Android。
计算机的体系结构
以上是常识,看一看就好了。
计算机语言的概述
语言是人之间的沟通语言,计算机语言是人和计算机的沟通语言。计算机底层只认识0,1.
计算机语言的发展
• 第一代语言:机器语言
指令以二进制代码形式存在,最开始使用穿孔卡片。
• 第二代语言:汇编语言。
使用助记符表示一条机器指令,如:ADD、SUB等。
• 第三代语言:高级语言
Java、C ,C++,PHP , Python,Scala等。
Java的江湖地位:龙头老大。其他的语言百度一下,到处都是介绍。
Java的发展历史:
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正式发布。
• Java SE(Java Platform, Standard Edition)称之为“Java平台标准版”,是
Java平台的基础。
• Java SE包含了运行Java应用所需要的基础环境和核心类库。
• Java SE还定义了基于桌面应用的基础类库,通过使用这些类库,我们可
以编写出类似于像Office那样的丰富多彩的桌面应用。• Java EE(Java Platform,Enterprise Edition)称之为“Java平台企业版”。
• Java EE构建在Java SE基础之上,用于构建企业级应用。所谓企业级应用
是指那些为商业组织、大型企业而创建的应用系统,例如:电信的“计费
系统”、银行的“网银系统”、企业中的“客户关系管理系统”等等。
简要概述一下,工作里面主要使用javaEE,但是javaSE是javaEE的基础。
还有一个已经淘汰了的JavaME,不用管了。
Java软件的下载
开发工具的下载和安装
• 下载方式
• 方式一:通过官网下载 www.sun.com www.oracle.com
• 方式二:通过搜索下载 www.baidu.com www.sogou.com
• 安装方式
• 若下载的是安装版,则一路点击下一步安装即可;
• 若下载的是绿色版,则直接解压即可;
• 无论是安装版还是绿色版,切记安装的路径中不要有中文!
Jdk的目录结构
• bin目录 - 该目录下主要存放JDK的各种工具命令。
• conf目录 - 该目录下主要存放jdk的相关配置文件。
• include目录 - 该目录下主要存放了一些平台的头文件。
• jmods目录 - 该目录下主要存放了JDK的各种模块。
• legal目录 - 该目录下主要存放了JDK各模块的授权文档。
• lib目录 - 该目录下主要存放了JDK工具的一些补充jar包和源代码。相关的概念
• JDK - 称为Java开发工具包( Java Development Kit)。Java开发人士需
要下载和安装JDK,目前的主流版本为JDK11。
• JRE - 称之为Java SE运行时环境(Java SE Runtime Environment),提供
了运行Java应用程序所必须的软件环境等。无论是开发还是运行Java应都必须安装。相关的概念
• javac.exe - 编译器,主要用于将高级Java源代码翻译成字节码文件。
• java.exe - 解释器,主要用于启动JVM对字节码文件进行解释并执行。
Jdk、jre、jvm之间的关系:jdk包括jre,jre包括jvm.
Java开发的常用工具
• 文本编辑器(TE,Text Editor)
• 记事本、Notepad++、Edit Plus、UltraEdit、…
• 集成开发环境(IDE,Integrated Development Environment )
• Jbuilder、NetBeans、Eclipse、MyEclipse、IDEA、…编写Java程序的流程
• 新建文本文档,将文件扩展名由xxx.txt修改为xxx.java;
• 使用记事本/Notepad++的方式打开文件,编写Java代码后进行保存;
• 启动dos窗口,并切换到.java文件所在的路径中;
• 使用javac xxx.java进行编译,生成xxx.class的字节码文件;
• 使用java xxx 进行解释执行,打印最终结果;常见的错误
• 错误: 需要class, interface或enum => 通常都是class关键字拼写错误
• 错误: 找不到符号 => 通常因为单词拼写错误或Java中不支持这样的单词
• 错误: 需要’;’ => 通常都是因为少写分号,加上英文版分号即可
• 错误: 非法字符: ‘\uff1b’ => 通常是因为出现了中文标点符号,修改为英
文版即可
• 错误: 在类 PrintTest 中找不到 main 方法, 请将 main 方法定义为: =>
main写成了mian
常用的快捷键
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 启动任务管理器
注释
• 注释用于进行代码说明,是给程序员看的文字描述,编译器会忽略注释。
• 基本分类
// 单行注释 ,从 // 开始,到本行结束,都是注释。
/* / 多行注释,从/ 开始,到*/结束,中间所有都是注释。
/** */ 多行/文档注释,从/*开始,到/结束,是一种支持提取的注释。
• 多行注释不允许嵌套使用!
环境变量的配置
• 基本概念
通常情况下可执行文件只能在该文件所在的路径中使用,为了使得该可
执行文件可以在任意路径中使用,则需要将该文件所在的路径信息配置到
环境变量Path中。
环境变量的配置
• 配置方式
计算机 => 右击,选择属性 => 高级系统设置 => 高级 => 环境变量 =>
系统变量 => 找到Path,点击编辑 => 将javac.exe所在的路径(就是jdk的bin包)信息配置到
Path变量值的最前面,加上英文版的分号 => 一路点击确定即可
• 注意事项
切记Path变量原来的变量值不要删除,配置完毕后记得重启dos窗口!
跨平台原理:一次编译,到处运行
因为底层有jvm虚拟机,所以电脑安装jvm以后,把字节码文件翻译成为该平台可以认识的东西,类似于一个翻译,将你的话翻译给别人,你只需要做自己的事情,jvm帮你翻译。
任务二: 变量和数据类型
变量的基本概念
• 当需要在程序中记录单个数据内容时,则声明一个变量即可,而声明变
量的本质就是在内存中申请一个存储单元,由于该存储单元中的数据内
容可以发生改变,因此得名为"变量"
。
• 由于存放的数据内容大小不一样,导致所需存储单元的大小不一样,在
Java语言中使用数据类型加以描述,为了便于下次访问还需要给该变量指
定一个名字,用于记录该变量对应的存储单元。
变量的声明方式
• 数据类型 变量名 = 初始值;
• 其中=初始值可以省略,但;不可以省略变量的注意事项
• Java是强类型语言,变量在使用前必须声明来指明其数据类型。
• 变量在使用之前必须初始化。
• 变量不能重复声明标识符的命名法则(笔试)
• 由数字、字母、下划线以及$等组成,其中数字不能开头(后面讲到)。
• 不能使用Java语言的关键字,所谓关键字就是Java语言用于表示特殊含义
的单词。
• 区分大小写,长度没有限制但不宜过长。
• 尽量做到见名知意,支持中文但不推荐使用。
• 标识符可以给类/变量/属性/方法/包 起名字。
案例题目
• 提示用户从键盘输入自己的姓名和年龄信息并打印出来。
import org.junit.Test;
import java.util.Scanner;
public class Test1 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入你的年龄和名字:");
int age = input.nextInt();
String name = input.next();
System.out.println("年龄是:" + age + ",名字是:" + name);
}
public static void main(String[] args,int i) {
}
}
数据类型的分类
• 在Java语言中数据类型主要分为两大类:
• (1)基本数据类型(记住)
byte、short、int、long、float、double、boolean、char
• (2)引用数据类型(了解)
数组、类、接口、枚举、标注
常用的进制
• 在日常生活中采用十进制进行数据的描述,逢十进一,十进制权重是:
100、101、10^2、…
• 在计算机的底层采用0和1组成的二进制序列进行数据的描述,逢二进一,
二进制的权重是20、21、2^2、…
• 二进制中的最高位(最左边)用于代表符号位,若该位是0则表示非负数,
若该位是1则表示负数。
• 八进制和十六进制其实都是二进制的简写。进制之间的转换
• 正十进制转换为二进制的方式
a.除2取余法,使用十进制整数不断地除以2取出余数,直到商为0时将
余数逆序排序。
b.拆分法,将十进制整数拆分为若干个二进制权重的和,有该权重下面
写1,否则写0。进制之间的转换
• 正二进制转换为十进制的方式
a.加权法,使用二进制中的每个数字乘以当前位的权重再累加起来。进制之间的转换
• 负十进制转换为二进制的方式
a.先将十进制的绝对值转换为二进制,然后进行按位取反再加1。
• 负数的需要补码:按位取反,再加1 。
进制之间的转换
• 负二进制转换为十进制的方式
a.先减1再按位取反,合并为十进制整数后添加负号。
单个字节表示的整数范围(重中之重)
• 在计算机中单个字节表示八位二进制位,其中最高位(最左边)代表符号位,
使用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.
整数类型
• 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。浮点类型
• Java语言中用于描述小数数据的类型:float 和 double,推荐double类型
• 其中float类型在内存空间占4个字节,叫做单精度浮点数,可以表示7位
有效数字,范围:-3.403E38~3.403E38。
• 其中double类型在内存空间占8个字节,叫做双精度浮点数,可以表示15
位有效数字,范围:-1.798E308~1.798E308。
• Java程序中直接写出的小数数据叫做直接量,默认为double类型,若希望
表达float类型的直接量,则需要在直接量的后面加上f或者F.布尔类型
• Java语言中用于描述真假信息类型有:boolean,数值只有:true 和 false。
• 布尔类型在内存空间中所占大小没有明确的规定,可以认为是1个字节。字符类型
• 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位。它包括了ASCII码。
• 要求掌握的转义字符有:" - " ’ - ’ \ - \ \t - 制表符 \n - 换行符基本数据类型之间的转换
• Java语言中基本数据类型之间的转换方式:自动类型转换和强制类型转换。
• 其中自动类型转换主要指从小类型到大类型之间的转换。
简要描述:你要把100ml容量杯子里面的水倒入1000ml的水,在怎么样都不可能出现水溢出,所以不用担心,就是可以实现自动转换。
基本数据类型之间的转换
• 其中强制类型转换主要指从大类型到小类型之间的转换,语法格式如下:
目标类型 变量名 = (目标类型)源类型变量名;
• 强转有风险,操作需谨慎!
简要描述:你要把1000ml容量杯子里面的水倒入100ml的水,是不是有可能出现水溢出。所以要加强制转换,表示知道可能会出现问题。
任务三:运算符算术运算符
• + 表示加法运算符
• - 表示减法运算符
• * 表示乘法运算符
• / 表示除法运算符
• % 表示取模
/取余运算符
案例:
• 提示用户输入正整数类型的秒数,拆分秒数后输出x小时x分x秒。
• 如:输入7199,输出1小时59分59秒。
代码实现:
import org.junit.Test;
import java.math.BigInteger;
import java.util.Scanner;
public class Test1 {
public static void main (String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入秒数:");
int seconds = input.nextInt();
int hour = seconds / 3600;
int minute = seconds % 3600 / 60;
int second = seconds % 60;
System.out.println("当前时间是 :" + hour + "时:" + minute + "分:" + second+ "秒");
}
}
字符串连接运算符
• + 可以实现字符串的连接。同时可以实现字符串与其他数据类型“相连”。
System.out.println(“当前时间是 :” + hour + “时:” + minute + “分:” + second+ “秒”);
System.out.println(1 + “123”); //结果为1123
关系/比较运算符
• > 表示是否大于运算符 >= 表示是否大于等于运算符
• < 表示是否小于运算符 <= 表示是否小于等于运算符
• == 表示是否等于运算符 != 表示是否不等于运算符
• 所有以关系运算符作为最终运算的表达式结果一定是boolean类型。
案例题目
• 提示用户输入一个整数,使用关系运算符判断该整数是否为负数,若是
则打印true,若不是则打印false。
import org.junit.Test;
import java.math.BigInteger;
import java.util.Scanner;
public class Test1 {
public static void main (String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入一个数:");
int seconds = input.nextInt();
if(seconds > 0) {
System.out.println(true);
} else {
System.out.println(false);
}
}
}
自增减运算符
• ++ 表示自增运算符,用于使得当前变量自身的数值加1的效果
• – 表示自减运算符,用于使得当前变量自身的数值减1的效果
• 只能用于变量,常数不可以
逻辑运算符
• && 表示逻辑与运算符,相当于"并且",同真为真,一假为假。
• || 表示逻辑或运算符,相当于"或者",一真为真,同假为假。
• ! 表示逻辑非运算符,相当于"取反",真为假,假为真。
• 逻辑运算符的操作数均为boolean表达式。
逻辑运算符的短路特性
• 对于逻辑与运算符来说,若第一个表达式为假则结果为假,此时跳过第
二个表达式;
• 对于逻辑或运算符来说,若第一个表达式为真则结果为真,此时跳过第
二个表达式;
案例题目
• 提示用户输入一个正整数,使用逻辑运算符判断该正整数是否为三位数,
若是则打印true,否则打印false。
import org.junit.Test;
import java.math.BigInteger;
import java.util.Scanner;
public class Test1 {
public static void main (String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入一个数:");
int seconds = input.nextInt();
if(seconds > 99 && seconds < 1000) {
System.out.println("是三位数");
} else {
System.out.println("不是三位数");
}
}
}
条件/三目运算符
• 条件表达式? 表达式1: 表达式2
• 判断条件表达式是否成立,若成立则执行表达式1,否则执行表达式2 。
案例题目
• 提示用户输入两个整数,使用三目运算符找到最大值并打印出来。
import org.junit.Test;
import java.math.BigInteger;
import java.util.Scanner;
public class Test1 {
public static void main (String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入两个数:");
int a = input.nextInt();
int b = input.nextInt();
System.out.println(a + "和" + b + "中较大的值是 " +( a > b ? a:b));
}
}
赋值运算符
• = 表示赋值运算符,用于将=右边的数据赋值给=左边的变量,覆盖变量
原来的数值。
• 赋值表达式本身也有值,其本身之值即为所赋之值。
• +=、 -=
、
*=
、 /=、 …
重点,笔试题考点
考点1:
byte b1 = 12;
b1 = (byte) (b1 + 2); //b1 = b1 + 2,结果类型为int,需要自己强转
b1 += 2; //b1 += 2; 编译器会自动优化,转换为byte,
考点2:
Int a = 12;
2 == a 2 == a 和a == 2 结果一样,但是推荐2 == a,因为 a == 2 容易写成a = 2
a == 2
2 = a //编译器报错,因为常量无法被赋值
a = 2
移位运算符(了解)
• << 左移运算符,用于将数据的二进制位向左移动,右边使用0补充
• >> 右移运算符,用于将数据的二进制位向右移动,左边使用符号位补充
• >>> 表示逻辑右移运算符,用于将数据的二进制位向右移动,左边使用0
补充。
位运算符(了解)
• & 表示按位与运算符,按照二进制位进行与运算,同1为1,一0为0.
• | 表示按位或运算符,按照二进制位进行或运算,一1为1,同0为0.
• ~ 表示按位取反运算符,按照二进制位进行取反,1为0,0为1.
• ^ 表示按位异或运算符,按照二进制位进行异或运算,同为0,不同为1.
运算符的优先级
• ()的优先级极高。
• =的优先级极低。
• 若无法确认优先级,则使用()来确保即可。
任务四:执行流程
生活之中做事情大家有没有想过有哪些做的方式?是顺序去做,还是挑着做?计算机里面做事的流程有三种,顺序,选择,循环。
1.顺序:没什么好说的,代码从上到下执行。
2.选择:判断是否符合条件的执行
3.循环:闹钟好比。
现在说一下选择结构:
if分支结构
• 判断条件表达式是否成立
=> 若成立,则执行语句块;
=> 若不成立,则跳过语句块;
案例题目
• 提示用户输入两个整数,使用if分支结构找到最大值并打印出来。
int a = 100;
Int b = 100;
If(a > b) {
打印a;
} else {
打印b;
}
if else分支结构
• 判断条件表达式是否成立
=> 若成立,则执行语句块1;
=> 若不成立,则执行语句块2;
案例题目
• 提示用户输入一个整数,使用if else分支结构判断该整数是负数还是非负
数并打印。
• 使用if else分支结构判断该整数是正数、负数还是零
if else if else分支结构
• 判断条件表达式1是否成立
=> 若成立,则执行语句块1;
=> 若不成立,则判断条件表达式2是否成立
=> 若成立,则执行语句块2;
=> 若不成立,则执行语句块n;
其中else if (条件n) {
语句;
} 可以出现多次。
switch case分支结构
• 计算变量/表达式的数值 => 判断是否匹配字面值1
=> 若匹配,则执行语句块1 => 执行break跳出当前结构
=> 若不匹配,则判断是否匹配字面值2
=> 若匹配,则执行语句块2 => 执行break跳出当前结构
=> 若不匹配,则执行语句块default分支结构
• switch()中支持的数据类型有:byte、short、char以及int类型,从jdk1.5
开始支持枚举类型,从jdk1.7开始支持String类型。
一旦case后面没有break;那么只要遇到满足条件的执行完,会一直继续执行,直到switch执行完或者遇到break为止。
举个栗子:
switch(11){
case 11 :
输出11;
case 12 :
输出12;
Default :
输出defalut;
}
会把三句话都执行了。
2:循环结构
循环结构的概念
• 在Java程序中若希望重复执行一段代码时,就需要使用循环结构。
• 任何复杂的程序逻辑都可以通过顺序、分支、循环三种程序结构实现。
for循环
• 执行初始化表达式 => 判断条件表达式是否成立
=> 成立则执行循环体 => 修改初始值表达式 => 判断条件是否成立
=> 若不成立,则循环结束
案例题目
• 使用for循环打印1-100的所有奇数,使用三种方式。
案例题目
• 使用for循环实现累加:1+2+…+10000=?最后打印出来。
案例题目
• 使用for循环打印三位数中所有水仙花数。
• 所谓“水仙花数”即一个整数满足其值等于各个数位的立方和。
• 如:153是一个水仙花数,因为153=13+53+3^3。
continue关键字
• continue语句用在循环体中,用于结束本次循环而开始下一次循环。
案例题目
• 使用for循环打印1 ~ 20之间的所有整数,若遇到5的倍数则跳过不打印。break关键字
• break用于退出当前语句块,break用在循环体中用于退出循环。
• for(;😉 - 这种没有循环条件的循环叫做 无限循环,俗称“死循环”
。案例题目
• 不断地提示用户输入聊天内容并输出,直到用户输入”bye”结束聊天。案例题目
• 猜数字游戏
• 随机生成数字n(1-100), 等待用户输入猜测数据, 根据用户的输入比较输出
猜大了,猜小了,猜对了, 如果用户猜对了就结束游戏 。双重for循环的格式
• for(初始化表达式1; 条件表达式2; 修改初始值表达式3) {
for(初始化表达式4; 条件表达式5; 修改初始值表达式6) {
循环体;
}
}
双重for循环的执行流程
• 执行表达式1 => 判断表达式2是否成立
=> 若成立,则执行表达式4 => 判断表达式5是否成立
=> 若成立,则执行循环体 => 执行表达式6 => 表达式5是否成立
=> 若不成立,则内层循环结束 => 表达式3 => 表达式2是否成立
=> 若不成立,则外层循环结束双重for循环的特点
• 外层循环用于控制打印的行数,内层循环用于控制打印的列数,外层循
环改一下,内层循环从头到尾跑一圈。
• 在以后的开发中若需要打印多行多列时,需要使用双重循环。
• 多重循环不宜嵌套太多层,否则效率很低。一般到三重循环即可,最常
见的就是双重循环。
break关键字跳出多层循环
• 在嵌套的循环结构中,break用于退出所在循环体。
• 如果要退出外层循环体,需要使用标号的方式。
for (…) { outer: for (…) {
for(…) { for(…) {
break; break outer;
} }
} }
案例题目
• 使用双重for循环打印2~100之间的所有素数。
• 当一个数只能被1和它本身整除时,这个数就叫做素数或质数。
while循环
• while(条件表达式) {
循环体;
}
• 判断条件表达式是否成立
=> 若成立,则执行循环体 => 判断条件表达式是否成立
=> 若不成立,则循环结束
案例题目
• 使用while循环计算调和数列的和并打印,即: 1/1 + 1/2 + … + 1/n。
import java.util.Scanner;
public class test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println(“请输入一个数:”);
int n = input.nextInt();
int i = 1;
double sum = 0;
while(i <= n) {
sum += 1.0 / i;
i++;
}
System.out.println(sum);
}
}
while循环和for循环比较
• while循环和for循环完全可以互换,当然推荐使用for循环。
• while循环更适合于明确循环条件但不明确循环次数的场合中。
• for循环更适合于明确循环次数或范围的场合中。
• while(true) 等价于 for(;😉 都表示无限循环。
案例题目
• 提示用户输入一个任意位数的正整数然后反向输出。
do while循环(熟悉)
• do {
循环体;
} while(条件表达式);
• 执行循环体 => 判断条件表达式是否成立
=> 若成立,则执行循环体 => 判断条件表达式是否成立
=> 若不成立,则循环结束do while循环
• do-while循环主要用于至少执行一次循环体的场合中。案例题目
• 使用do while循环来模拟学习任务是否合格的检查, 如果合格则停止,
否则就重新完成学习任务。
import java.util.Scanner;
public class test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println(“请输入你是否认真学习(y/n):”);
String message = input.next();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
do{
System.out.println("请输入你是否认真学习(y/n):");
message = input.next();
}while(!message.equals("y"));
}
}
任务五:数组的概念和应用
现在我提一个问题,如果我需要存储六七个学生的成绩,大家第一反应是什么?是不是定义六七个变量来存储,这是对的,完全没有问题。但是当一个学校需要存储两千个学生的成绩时,还可以定义两千个变量吗?答案是否定的,因为这不是正常人可以管理维护的了,所以数组登场了。下面是简要介绍:
• 当需要在Java程序中记录多个类型相同的数据内容时,则声明一个一维数
组即可,一维数组本质上就是在内存空间中申请一段连续的存储单元。
• 数组是相同数据类型的多个元素的容器,元素按线性顺序排列,在Java语
言中体现为一种引用数据类型。
一维数组的声明方式
• 数据类型[] 数组名称 = new 数据类型[数组的长度];
• 调用数组的length属性可以获取数组的长度:
• 可以通过下标的方式访问数组中的每一个元素。需要注意的是:数组的
下标从0开始,对于长度为n的数组,下标的范围是0~n-1。
一维数组的初始化方式
• 基本类型的数组(数据元素为基本类型)创建后,其元素的初始值:byte、
short、char、int、long为0;float和double为0.0;boolean为false。
• 可以在数组声明的同时进行初始化,具体如下:
数据类型[] 数组名称 = {初始值1, 初始值2, …};
代码:
/*
编程实现一维数组的声明和使用
*/
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 ~ 1
System.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
}
}
}
内存结构之栈区,这是jvm的知识,大家稍微了解一下就好了,后面我学到了会仔细的总结。
• 栈用于存放程序运行过程当中所有的局部变量。一个运行的Java程序从开
始到结束会有多次变量的声明。
内存结构之堆区
• 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,若有则修改为220
for(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();
}
}
数组的优缺点
• 可以直接通过下标(或索引)的方式访问指定位置的元素,速度很快。
• 数组要求所有元素的类型相同。
• 数组要求内存空间连续,并且长度一旦确定就不能修改。
• 增加和删除元素时可能移动大量元素,效率低。
案例题目(大家自己做一下,就不给答案了)
• 声明一个初始值为11 22 33 44 55的一维数组并打印所有元素
• 声明一个长度为3元素类型为int类型的一维数组并打印所有元素
• 实现将第一个数组中间3个元素赋值到第二个数组中
• 再次打印第二个数组中的所有元素
案例题目(大家自己做一下,就不给答案了)
• 编程统计用户输入任意一个正整数中每个数字出现次数的统计并打印。
• 如:123123 => 1出现2次,2出现2次,3出现2次
案例题目(大家自己做一下,就不给答案了)
• 提示用户输入学生的人数以及每个学生的考试成绩并打印出来。
• 计算该班级的总分和平均分并打印出来。
数组工具类的概念
• java.util.Arrays类可以实现对数组中元素的遍历、查找、排序等操作。数组工具类的常用方法
• 常用方法如下:
数组工具类的使用
/*
编程实现数组工具类的使用
*/
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中的每个元素,也就是给数组中每个元素赋值为10
Arrays.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,否则打印false
System.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 要求顺序要相同
}
}
第二节:二维数组(熟悉)
表格大家都用过吧,分为行和列,就像排队的方阵一样。同样的道理,二维数组就是这种样子,有行和列。
二维数组的概念
• 二维数组本质上就是由多个一维数组摞在一起组成的数组,二维数组中
的每个元素都是一维数组,而一维数组中的每个元素才是数据内容。
二维数组的声明和初始化方式
• 数据类型[][] 数组名称 = new 数据类型[行数][列数];
• 数据类型[][] 数组名称 = {{元素1, 元素2,…}, …};
/*
编程实现二维数组的声明和使用
*/
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];
}
}
二维数组的注意要点:数组的行数是数组的长度,比如arr3.Length = 数组的行数,每行的列数就是不确定了,所以定义的时候建议:数据类型[][] 数组名称 = new 数据类型[行数][];
列数不建议写进去。
/*
编程使用二维数组来实现杨辉三角的生成和遍历
*/
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或者列下标与当前行的行下标相等时,则对应位置的元素就是1
if(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();
}
}
}