Java-基础语法01
Java语言平台版本
-
JavaME(Java Platform Micro Edition)小型版
是为开发电子消费产品和嵌入式设备提供的解决方案,已经被安卓 IOS取代
-
JavaSE(Java Platform Standard Edition)标准版
是为开发普通桌面和商务应用程序提供的解决方案
该技术体系是基础,可以完成一些桌面应用程序的开发两者的基础 -
JavaEE(Java Platform Enterprise Edition)企业版
是为开发企业环境下的应用程序提供的一套解决方案
Java 语言的特点
| 简单性 | 面向对象 | 分布式 |
|---|---|---|
| 跨平台性 | 多线程 | 动态性 |
| 健壮性 | 安全性 |
Java跨平台
什么是平台
通过Java语言编写的应用程序在不同的系统平台上都可以运行
跨平台的原理
只要在需要运行java应用程序的操作系统上,先安装一个Java虚拟机(JVM Java Virtual Machine)即可。由JVM来负责Java程序在该系统中的运行。
总结
因为有了JVM,所以同一个Java程序在三个不同的操作系统中都可以执行。这样就实现了Java程序的可移植性。也称为Java具有良好的跨平台性。
JDK、JRE、JVM
-
JDK(Java Development Kit Java开发工具包)
JDK是提供给Java开发人员使用的,其中包含了java的开发工具,也包括了JRE。所以安装了JDK,就不用在单独安装JRE了。 其中的开发工具:编译工具(javac.exe) 执行工具(java.exe) 打包工具(jar.exe)等 -
JRE(Java Runtime Environment Java运行环境)
包括Java虚拟机(JVM Java Virtual Machine)和Java程序所需的核心类库等,如果想要运行一个开发好的Java程序,计算机中只需要安装JRE即可。 -
JVM(Java Virtual Machine Java虚拟机)
整个java实现跨平台的最核心的部分,保证程序的跨平台性,以及编译执行写好的java程序!总结
使用JDK开发完成的java程序,交给JRE去运行。由jvm保证跨平台性。
JDK、JRE、JVM 之间的关系
- JDK:包含了java的开发工具,也包括了JRE。
- JRE:包括Java虚拟机(JVM Java Virtual Machine)和Java程序所需的核心类库等
- JVM:是整个java实现跨平台的最核心的部分
总结
JDK 包含JRE JRE包含JVM ,开发中我们只需要安装JDK即可!
环境搭建
配置开发环境
为什么配置环境变量
开发Java程序,需要使用JDK提供的开发工具(比如javac.exe、java.exe等命令),而这些工具在JDK的安装目录的 bin目录下,如果不配置环境变量,那么这些命令只可以在该目录下执行。我们不可能把所有的java文件都放到JDK 的bin目录下,所以配置环境变量的作用就是可以使bin目录下的java相关命令可以在任意目录下使用。
jdk环境配置
JAVA_HOME:用于配置jdk安装路径,用于提供第三方软件支持
CLASSPATH:jdk1.5以后默认配置,无需配置(如果配置不要配错),配置源代码编译后生成位置
PATH:使bin下工具可以在任意路径下使用
注意:在修改环境变量之后需要重新打开cmd窗口
Java基础语法
什么是注释
注释是对代码的解释和说明文字,可以提高程序的可读性,因此在程序中添加必要的注释文字十分重要
注释的分类
-
单行注释
单行注释的格式是使用//,从//开始至本行结尾的文字将作为注释文字
// 这是单行注释文字 -
多行注释
多行注释的格式是使用/* 和 */将一段较长的注释括起来
/* 这是多行注释文字 这是多行注释文字 */ // 注意:多行注释不能嵌套使用。 -
文档注释
文档注释以
/**开始,以*/;补:结束文档注释可以书写相应的文档标签@autor 作者 @date 时间通过javadoc指令可以生成文档(现在已经不用了)/**这是文档注释的内容*/
注意:注释会在编译期间自动忽略(不会编译到class文件中)
关键字
什么是关键字
关键字是指被java语言赋予了特殊含义的单词
关键字的特点
关键字的字母全部小写。
单词
常用的代码编辑器对关键字都有高亮显示,比如现在我们能看到的public、class、static等。
常用的关键字51+2个
2个保留字const goto
常量
什么是常量
在程序运行过程中,其值不可以发生改变的量。
Java中常量的分类
-
字符串常量
用双引号括起来的多个字符(可以包含0个、一个或多个),例如"a"、"abc"、"中国"等
-
整数常量
整数,例如:-10、0、88等
-
小数常量
小数,例如:-5.5、1.0、88.88等
-
字符常量
用单引号括起来的一个字符,例如:'a'、'5'、'B'、'中'等
-
布尔常量
布尔值,表示真假,只有两个值true和false
-
空常量
一个特殊的值,空值,值为null
常量演示
除空常量外,其他常量均可使用输出语句直接输出
/*
常量的分类:
字符串常量 "123" "abc"
整数常量: 100 1 -1 -100
小数常量: 1.1 1.2 -1.1 -1.2
字符常量: 'a' '1' '你'
字符'' 有且仅有一个字符
布尔常量: true false
空常量: null
// null是不能直接打印,有特殊应用的,在后面的数组 集合 对象中使用
// System.out.println(null);
*/
在java中会将常量存储在在常量池中
在jvm运行过程中会将程序中所有的常量数据存储在常量池中(第一次使用)
在实际执行过程中虚拟机执行代码读取执行过程中发现存在常量,会先去常量池中查找是否存在,如果不存在则开辟空间存储数据,如果存在则直接返回,只有当程序执行结束后GC(垃圾回收器)会自动回收(删除数据释放资源)
数据类型
计算机存储单元
我们知道计算机是可以用来存储数据的,但是无论是内存还是硬盘,计算机存储设备的最小信息单元叫“位(bit)”,我们又称之为“比特位”,通常用小写的字母”b”表示。而计算机中最基本的存储单元叫“字节(byte)”,
通常用大写字母”B”表示,字节是由连续的8个位组成。
存储单位换算
除了字节外还有一些常用的存储单位,其换算单位如下
1B(字节) = 8bit
1KB = 1024B
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB
1PB = 1024TB
1EB = 1024PB
Java中的数据类型
-
为什么有数据类型
Java是一个强类型语言,对每一种数据都规定了范围.
-
数据类型的分类
-

-
基本数据类型

-
注意
e+38表示是乘以10的38次方,同样,e-45表示乘以10的负45次方。
在java中整数默认是int类型,浮点数默认是double类型
变量
什么是变量
在程序运行过程中,其值可以在一定范围内发生改变的量,从本质上讲,变量是内存中的一小块区域,其值可以在一定范围内变化
变量定义的格式
-
格式一
数据类型 变量名 = 初始化值; // 声明变量并赋值int age = 18; System.out.println(age); -
格式二
// 先声明,后赋值(使用前赋值即可) 数据类型 变量名; 变量名 = 初始化值;double money; money = 55.5; System.out.println(money); -
格式三
在同一行定义多个同一种数据类型的变量,中间使用逗号隔开
数据类型 变量名 = 值,变量名 = 值, ....;int a = 10, b = 20; // 定义int类型的变量a和b,中间使用逗号隔开 System.out.println(a); System.out.println(b); int c,d; // 声明int类型的变量c和d,中间使用逗号隔开 c = 30; d = 40; System.out.println(c); System.out.println(d);
变量注意事项
1. 在同一对花括号中,变量名不能重复。
2. 变量在使用之前,必须初始化(赋值)。
3. 定义long类型的变量时,需要在整数的后面加L(大小写均可,建议大写)。因为整数默认是int类型,整数太大可能超出int范围。
4. 定义float类型的变量时,需要在小数的后面加F(大小写均可,建议大写)。因为浮点数的默认类型是double, double的取值范围是大于float的,类型不兼容。
5. 变量实际存储的是数据的地址,修改的也是地址
注:声明的变量保存在栈中,栈中不保存数据,实际保存的是数据的地址,变量修改实际修改的是保存的地址
注意:修改变量数据,也不会删除对应常量,常量池中的数据gc回收实际为程序执行结束
标识符
什么是标识符
标识符是用户编程时使用的名字,用于给类、方法、变量、常量等命名。
标识符的组成规则
由字母、数字、下划线“_”、美元符号“$”组成,第一个字符不能是数字。
不能使用java中的关键字作为标识符。
标识符对大小写敏感(区分大小写)。
标识符的命名规范
见名知意:根据名字知道标识符对应功能
驼峰命名法:如果标识符由多个单词组成除首个单词首字母外其余单词首字母大写 passWord
-
类名
一个单词: 首字母大写 Hello
多个单词: 每一个单词的首字母都要大写 HelloWorld (大驼峰) -
变量名和方法
一个单词: 全部小写 value get()
多个单词: 从第二个单词的首字母开始,每一个单词都要大写 maxValue getValue() (小驼峰)
-
包
一个单词: 全部小写 cn com
多个单词: 全部小写中间用
.分割 cn.yunhe公司的域名倒着写
www.baidu.com-->com.baidu.xxx
-
自定义常量
一个单词: 全部大写 MAX VALUE
多个单词: 全部大写 中间用 _ 隔开 MAX_VALUE
类型转换
自动类型转换
把一个表示数据范围小的数值或者变量赋值给另一个表示数据范围大的变量。这种转换方式是自动的,直接书写即可。
-
示例
double num = 10; // 将int类型的10直接赋值给double类型 System.out.println(num); // 输出10.0
强制类型转换
把一个表示数据范围大的数值或者变量赋值给另一个表示数据范围小的变量。
-
强制类型转换格式
目标数据类型 变量名 = (目标数据类型)值或者变量;
-
示例
double num1 = 5.5; int num2 = (int) num1; // 将double类型的num1强制转换为int类型 System.out.println(num2); // 输出5(小数位直接舍弃)
-
-
表示数据范围从小到大的图有两个 路线:
-
byte-->short -->int-->long--->float--->double
-
char--->int--->long--->float--->double
-
强制类型转换注意事项
-
char类型的数据转换为int类型是按照码表中对应的int值进行计算的。比如在ASCII码表中,'a'对应97。
int a = 'a'; System.out.println(a); // 将输出97 -
整数默认是int类型,byte、short和char类型数据参与运算均会自动转换为int类型。
byte b1 = 10; byte b2 = 20; byte b3 = b1 + b2; byte b4= 10+20; // 第三行代码会报错,b1和b2会自动转换为int类型,计算结果为int,int赋值给byte需要强制类型转换。 // 修改为: int num = b1 + b2; // 或者: byte b3 = (byte) (b1 + b2);
* boolean类型不能与其他基本数据类型相互转换。 -
运算符
什么是运算符
-
运算符
对常量或者变量进行操作的符号
-
表达式
用运算符把常量或者变量连接起来符合java语法的式子就可以称为表达式。 不同运算符连接的表达式体现的是不同类型的表达式。
-
举例说明
int a = 10; int b = 20; int c = a + b;+:是运算符,并且是算术运算符。
a + b:是表达式,由于+是算术运算符,所以这个表达式叫算术表达式。
算术运算符
| 符号 | 作用 | 说明 |
|---|---|---|
| + | 加 | 参看小学一年级 |
| - | 减 | 参看小学一年级 |
| * | 乘 | 参看小学二年级,与“×”相同 |
| / | 除 | 参看小学二年级,与“÷”相同 |
| % | 取余 | 获取的是两个数据做除法的余数 |
-
注意事项
/和%的区别:两个数据做除法,/取结果的商,%取结果的余数。
整数操作只能得到整数,要想得到小数,必须有浮点数参与运算。
int a = 10;
int b = 3;
System.out.println(a / b); // 输出结果3
System.out.println(a % b); // 输出结果1
字符的"+"操作
-
char类型参与算术运算
使用的是计算机底层对应的十进制数值。需要我们记住三个字符对应的数值
- 'a' -- 97 a-z是连续的,所以'b'对应的数值是98,'c'是99,依次递加
- 'A' -- 65 A-Z是连续的,所以'B'对应的数值是66,'C'是67,依次递加
- '0' -- 48 0-9是连续的,所以'1'对应的数值是49,'2'是50,依次递加
// 可以通过使用字符与整数做算术运算,得出字符对应的数值是多少 char ch1 = 'a'; System.out.println(ch1 + 1); // 输出98,97 + 1 = 98 char ch2 = 'A'; System.out.println(ch2 + 1); // 输出66,65 + 1 = 66 char ch3 = '0'; System.out.println(ch3 + 1); // 输出49,48 + 1 = 49 -
算术表达式
算术表达式中包含不同的基本数据类型的值的时候,整个算术表达式的类型会自动进行提升。
-
提升规则
byte类型,short类型和char类型将被提升到int类型,不管是否有其他类型参与运算。 整个表达式的类型自动提升到与表达式中最高等级的操作数相同的类型 等级顺序:byte,short,char --> int --> long --> float --> double -
演示
byte b1 = 10; byte b2 = 20; // byte b3 = b1 + b2; // 该行报错,因为byte类型参与算术运算会自动提示为int,int赋值给byte可能损失精度 int i3 = b1 + b2; // 应该使用int接收 byte b3 = (byte) (b1 + b2); // 或者将结果强制转换为byte类型 ------------------------------- int num1 = 10; double num2 = 20.0; double num3 = num1 + num2; // 使用double接收,因为num1会自动提升为double类型正是由于上述原因,所以在程序开发中我们很少使用byte或者short类型定义整数。也很少会使用char类型定义字符,而使用字符串类型,更不会使用char类型做算术运算。
-
字符串的"+"操作
当“+”操作中出现字符串时,这个”+”是字符串连接符,而不是算术运算。
System.out.println("yunhe"+ 666); // 输出:yunhe666
在”+”操作中,如果出现了字符串,就是连接运算符,否则就是算术运算。当连续进行“+”操作时,从左到右逐个执行。
System.out.println(1 + 99 + "年云和"); // 输出:100年yunhe
System.out.println(1 + 2 + "yunhe" + 3 + 4); // 输出:3yunhe34
// 可以使用小括号改变运算的优先级
System.out.println(1 + 2 + "yunhe" + (3 + 4)); // 输出:3yunhe7
赋值运算符
赋值运算符的作用是将一个表达式的值赋给左边,左边必须是可修改的,不能是常量。
| 符号 | 作用 | 说明 |
|---|---|---|
| = | 赋值 | a=10,将10赋值给变量a |
| += | 加后赋值 | a+=b,将a+b的值给a |
| -= | 减后赋值 | a-=b,将a-b的值给a |
| *= | 乘后赋值 | a*=b,将a×b的值给a |
| /= | 除后赋值 | a/=b,将a÷b的商给a |
| %= | 取余后赋值 | a%=b,将a÷b的余数给a |
注意:
扩展的赋值运算符隐含了强制类型转换。
short s = 10;
s = s + 10; // 此行代码报出,因为运算中s提升为int类型,运算结果int赋值给short可能损失精度
s += 10; // 此行代码没有问题,隐含了强制类型转换,相当于 s = (short) (s + 10);
自增自减运算符
| 符号 | 作用 | 说明 |
|---|---|---|
| ++ | 自增 | 变量的值加1 |
| -- | 自减 | 变量的值减1 |
- 注意事项:
- ++和-- 既可以放在变量的后边,也可以放在变量的前边。
- 单独使用的时候, ++和-- 无论是放在变量的前边还是后边,结果是一样的。
- 参与操作的时候,如果放在变量的后边,先拿变量参与操作,后拿变量做++或者--。
- 参与操作的时候,如果放在变量的前边,先拿变量做++或者--,后拿变量参与操作。
- 最常见的用法:单独使用。
int i = 10;
i++; // 单独使用
System.out.println("i:" + i); // i:11
int j = 10;
++j; // 单独使用
System.out.println("j:" + j); // j:11
int x = 10;
int y = x++; // 赋值运算,++在后边,所以是使用x原来的值赋值给y,x本身自增1
System.out.println("x:" + x + ", y:" + y); // x:11,y:10
int m = 10;
int n = ++m; // 赋值运算,++在前边,所以是使用m自增后的值赋值给n,m本身自增1
System.out.println("m:" + m + ", m:" + m); // m:11,m:11
练习:
int x = 10;
int y = x++ + x++ + x++;
System.out.println(y); // y的值是多少?
/*
解析,三个表达式都是++在后,所以每次使用的都是自增前的值,但程序自左至右执行,所以第一次自增时,使用的是10进行计算,但第二次自增时,x的值已经自增到11了,所以第二次使用的是11,然后再次自增。。。
所以整个式子应该是:int y = 10 + 11 + 12;
输出结果为33。
*/
注意:通过此练习深刻理解自增和自减的规律,但实际开发中强烈建议不要写这样的代码!小心挨打!
关系运算符
关系运算符有6种关系,分别为小于、小于等于、大于、等于、大于等于、不等于。
| 符号 | 说明 |
|---|---|
| == | a==b,判断a和b的值是否相等,成立为true,不成立为false |
| != | a!=b,判断a和b的值是否不相等,成立为true,不成立为false |
| > | a>b,判断a是否大于b,成立为true,不成立为false |
| >= | a>=b,判断a是否大于等于b,成立为true,不成立为false |
| < | a<b,判断a是否小于b,成立为true,不成立为false |
| <= | a<=b,判断a是否小于等于b,成立为true,不成立为false |
-
注意事项
-
关系运算符的结果都是boolean类型,要么是true,要么是false。
-
千万不要把
“==”误写成“=”,"=="是判断是否相等的关系,"="是赋值。
-
int a = 10;
int b = 20;
System.out.println(a == b); // false
System.out.println(a != b); // true
System.out.println(a > b); // false
System.out.println(a >= b); // false
System.out.println(a < b); // true
System.out.println(a <= b); // true
// 关系运算的结果肯定是boolean类型,所以也可以将运算结果赋值给boolean类型的变量
boolean flag = a > b;
System.out.println(flag); // 输出false
逻辑运算符
逻辑运算符把各个运算的关系表达式连接起来组成一个复杂的逻辑表达式,以判断程序中的表达式是否成立,判断的结果是 true 或 false。
| 符号 | 作用 | 说明 |
|---|---|---|
| & | 逻辑与 | a&b,a和b都是true,结果为true,否则为false |
| | | 逻辑或 | a|b,a和b都是false,结果为false,否则为true |
| ^ | 逻辑异或 | a^b,a和b结果不同为true,相同为false |
| ! | 逻辑非 | !a,结果和a的结果正好相反 |
短路逻辑运算符
| 符号 | 作用 | 说明 |
|---|---|---|
| && | 短路与 | 作用和&相同,但是有短路效果 |
| || | 短路或 | 作用和|相同,但是有短路效果 |
在逻辑与运算中,只要有一个表达式的值为false,那么结果就可以判定为false了,没有必要将所有表达式的值都计算出来,短路与操作就有这样的效果,可以提高效率。同理在逻辑或运算中,一旦发现值为true,右边的表达式将不再参与运算。
-
逻辑与&,无论左边真假,右边都要执行。
-
短路与&&,如果左边为真,右边执行;如果左边为假,右边不执行。
-
逻辑或|,无论左边真假,右边都要执行。
-
短路或||,如果左边为假,右边执行;如果左边为真,右边不执行。
int x = 3;
int y = 4;
System.out.println((x++ > 4) & (y++ > 5)); // 两个表达都会运算
System.out.println(x); // 4
System.out.println(y); // 5
System.out.println((x++ > 4) && (y++ > 5)); // 左边已经可以确定结果为false,右边不参与运算
System.out.println(x); // 4
System.out.println(y); // 4
位运算符
用于按位进行数据计算的运算符(与逻辑运算符相似)
| 符号 | 说明 |
|---|---|
| & | a&b, 将a与b的值按位进行与运算 |
| | | a|b, 将a与b的值按位进行或运算 |
| ~ | ~a, 将a值按位进行取反运算 |
| ^ | a^b, 将a与b的值按位进行异或运算 |
//位运算符
//将十进制数据转换为二进制之后 逐位进行对应的运算
public class Test5 {
public static void main(String[] args) {
//结果的二进制会自动再转换为十进制输出
// 6->0110
// 3->0011
//0代表false 1代表true
//6&3 0010->2
System.out.println(6&3);
//~6 实际计算机存储数据为63位 1位符号位
System.out.println(~6);
//右移
System.out.println(6>>2);
//左移
System.out.println(6<<2);
}
}
三元运算符
三元运算符语法格式
关系表达式 ? 表达式1 : 表达式2;
-
格式解析
问号前面的位置是判断的条件,判断结果为boolean型,为true时调用表达式1,为false时调用表达式2。其逻辑为:如果条件表达式成立或者满足则执行表达式1,否则执行第二个。
-
举例
int a = 10; int b = 20; int c = a > b ? a : b; // 判断 a>b 是否为真,如果为真取a的值,如果为假,取b的值
数据输入
我们可以通过 Scanner 类来获取用户的输入。使数据达到灵活性
使用步骤
导包
Scanner 类在java.util包下,所以需要将该类导入。导包的语句需要定义在类的上面。
import java.util.Scanner;
创建Scanner对象
Scanner sc = new Scanner(System.in);// 创建Scanner对象,sc表示变量名,其他均不可变
接收数据
int i = sc.nextInt(); // 表示将键盘录入的值作为int数返回。
示例:
import java.util.Scanner;
public class ScannerDemo {
public static void main(String[] args) {
//创建对象
Scanner sc = new Scanner(System.in);
//接收数据
int x = sc.nextInt();
//输出数据
System.out.println("x:" + x);
}
}
流程控制语句
在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的。所以,我们必须清楚每条语句的执行流程。而且,很多时候要通过控制语句的执行顺序来实现我们想要的功能。
流程控制语句分类
顺序结构
分支结构(if, switch)
循环结构(for, while, do…while)
顺序结构
顺序结构是程序中最简单最基本的流程控制,没有特定的语法结构,按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。
顺序结构执行流程图
开始----->语句A----->语句B----->语句C----->结束
分支结构之if语句
if格式一
if (关系表达式) {
语句体;
}
-
执行流程
①首先计算关系表达式的值
②如果关系表达式的值为true就执行语句体
③如果关系表达式的值为false就不执行语句体
④继续执行后面的语句内容
执行顺序:----->关系表达式---->true----->语句体---->其他语句
若关系表达式为false------>跳过语句体---->其他语句
-
代码示例
public class IfDemo { public static void main(String[] args) { System.out.println("开始"); //定义两个变量 int a = 10; int b = 20; //需求:判断a和b的值是否相等,如果相等,就在控制台输出:a等于b if(a == b) { System.out.println("a等于b"); } //需求:判断a和c的值是否相等,如果相等,就在控制台输出:a等于c int c = 10; if(a == c) { System.out.println("a等于c"); } System.out.println("结束"); } }
if格式二
if (关系表达式) {
语句体1;
} else {
语句体2;
}
-
执行流程
①首先计算关系表达式的值
②如果关系表达式的值为true就执行语句体1
③如果关系表达式的值为false就执行语句体2
④继续执行后面的语句内容
执行顺序:----->关系表达式为---->true----->语句体1---->其他语句
若关系表达式为---->false------>跳过语句体2---->其他语句
-
代码示例
public class IfDemo02 { public static void main(String[] args) { System.out.println("开始"); //定义两个变量 int a = 10; int b = 20; b = 5; //需求:判断a是否大于b,如果是,在控制台输出:a的值大于b,否则,在控制台输出:a的值不大于b if(a > b) { System.out.println("a的值大于b"); } else { System.out.println("a的值不大于b"); } System.out.println("结束"); } } -
if语句案例:奇偶数
-
需求
任意给出一个整数,请用程序实现判断该整数是奇数还是偶数,并在控制台输出该整数是奇数还是偶数。
-
分析
①为了体现任意给出一个整数,采用键盘录入一个数据
②判断整数是偶数还是奇数要分两种情况进行判断,使用if..else结构
③判断是否偶数需要使用取余运算符实现该功能 number % 2 == 0
④根据判定情况,在控制台输出对应的内容
-
代码实现
import java.util.Scanner;
public class IfTest01 {
public static void main(String[] args) {
//为了体现任意给出一个整数,采用键盘录入一个数据。(导包,创建对象,接收数据)
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数:");
int number = sc.nextInt();
//判断整数是偶数还是奇数要分两种情况进行判断,使用if..else结构
//判断是否偶数需要使用取余运算符实现该功能 number % 2 == 0
//根据判定情况,在控制台输出对应的内容
if(number%2 == 0) {
System.out.println(number + "是偶数");
} else {
System.out.println(number + "是奇数");
}
}
} -
if格式三
if (关系表达式1) {
语句体1;
} else if (关系表达式2) {
语句体2;
}
…
else {
语句体n+1;
}
-
执行流程
①首先计算关系表达式1的值
②如果值为true就执行语句体1;如果值为false就计算关系表达式2的值
③如果值为true就执行语句体2;如果值为false就计算关系表达式3的值
④…
⑤如果没有任何关系表达式为true,就执行语句体n+1。
-
代码示例
键盘录入一个星期数(1,2,...7),输出对应的星期一,星期二,...星期日
import java.util.Scanner; public class IfDemo03 { public static void main(String[] args) { System.out.println("开始"); // 需求:键盘录入一个星期数(1,2,...7),输出对应的星期一,星期二,...星期日 Scanner sc = new Scanner(System.in); System.out.println("请输入一个星期数(1-7):"); int week = sc.nextInt(); if(week == 1) { System.out.println("星期一"); } else if(week == 2) { System.out.println("星期二"); } else if(week == 3) { System.out.println("星期三"); } else if(week == 4) { System.out.println("星期四"); } else if(week == 5) { System.out.println("星期五"); } else if(week == 6) { System.out.println("星期六"); } else { System.out.println("星期日"); } System.out.println("结束"); } } -
if语句格式3案例
-
案例需求
小明快要期末考试了,小明爸爸对他说,会根据他不同的考试成绩,送他不同的礼物,假如你可以控制小明的得分,请用程序实现小明到底该获得什么样的礼物,并在控制台输出。
-
案例分析
①小明的考试成绩未知,可以使用键盘录入的方式获取值
②由于奖励种类较多,属于多种判断,采用if...else...if格式实现
③为每种判断设置对应的条件
④为每种判断设置对应的奖励
-
案例代码
import java.util.Scanner; public class IfTest02 { public static void main(String[] args) { //小明的考试成绩未知,可以使用键盘录入的方式获取值 Scanner sc = new Scanner(System.in); System.out.println("请输入一个分数:"); int score = sc.nextInt(); //由于奖励种类较多,属于多种判断,采用if...else...if格式实现 //为每种判断设置对应的条件 //为每种判断设置对应的奖励 //数据测试:正确数据,边界数据,错误数据 if(score>100 || score<0) { System.out.println("你输入的分数有误"); } else if(score>=95 && score<=100) { System.out.println("山地自行车一辆"); } else if(score>=90 && score<=94) { System.out.println("游乐场玩一次"); } else if(score>=80 && score<=89) { System.out.println("变形金刚玩具一个"); } else { System.out.println("胖揍一顿"); } } }
-
三目运算符与分支语句区别
1、语法上的区别
三目运算符是运算符,分支语句是流程控制语句
2、返回结果的区别
三目运算符执行结束后必须创建变量保存结果,分支语句可以直接执行代码块
3、效率的区别(不重要)
初期三目运算符效率没有if高(初期的会计算所有结果),现在效率相同
4、使用的区别
进行简单判断且返回常量数据时,使用三目运算符
进行复杂条件判断时,使用分支语句
switch语句
switch语句格式
switch (表达式) {
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
...
default:
语句体n+1;
break;
}
执行流程
- 首先计算出表达式的值
- 其次,和case依次比较,一旦有对应的值,就会执行相应的语句,在执行的过程中,遇到break就会结 束。
- 最后,如果所有的case都和表达式的值不匹配,就会执行default语句体部分,然后程序结束掉。
注意:switch中表达式的结果可以为 int char 枚举 String
注意:如果switch中得case,没有对应break的话,则会出现case穿透的现象
练习
根据输入年月日输入当年已过天数
public class Test5 {
public static void main(String[] args) {
//根据输入年月日输入当年已过天数
Scanner scanner=new Scanner(System.in);
System.out.println("请输入年份");
int year=scanner.nextInt();
System.out.println("请输入月份");
int month=scanner.nextInt();
System.out.println("请输入日期");
int day=scanner.nextInt();
//思考:2021年 5月9日已过天数
//1月份天数+2月+3月+4月+9日期
//声明变量保存已过天数
int sumDay=0;
//根据年份计算二月天数
//二月天数
int twoDay=28;
if(year%4==0){
twoDay=29;
}
switch (month-1) {
case 11:
sumDay+=30;
case 10:
sumDay+=31;
case 9:
sumDay+=30;
case 8:
sumDay+=31;
case 7:
sumDay+=31;
case 6:
sumDay+=30;
case 5:
sumDay+=31;
case 4:
sumDay+=30;
case 3:
sumDay+=31;
case 2:
sumDay+=twoDay;
case 1:
sumDay+=31;
default:
sumDay+=day;
}
System.out.println("已过"+sumDay+"天");
}
}
注意:如果switch中得case,没有对应break的话,则会出现case穿透的现象
for循环
循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体语句,当反复 执行这个循环体时,需要在合适的时候把循环判断条件修改为false,从而结束循环,否则循环将一直执行下去,形成死循环。
for循环结构
for (1初始化语句;2条件判断语句;4条件控制语句) {
3循环体语句;
}
for循环可以看做是while一定结构的简化书写
格式解释
- 初始化语句: 用于表示循环开启时的起始状态,简单说就是循环开始的时候什么样
- 条件判断语句:用于表示循环反复执行的条件,简单说就是判断循环是否能一直执行下去
- 循环体语句: 用于表示循环反复执行的内容,简单说就是循环反复执行的事情
- 条件控制语句:用于表示循环执行中每次变化的内容,简单说就是控制循环是否能执行下去
执行流程
①执行初始化语句
②执行条件判断语句,看其结果是true还是false
如果是false,循环结束
如果是true,继续执行
③执行循环体语句
④执行条件控制语句
⑤回到②继续
for循环案例
案例一:输出数据
-
需求
在控制台输出1-5和5-1的数据
-
代码实现
public class ForTest01 { public static void main(String[] args) { //需求:输出数据1-5 for(int i=1; i<=5; i++) { System.out.println(i); } System.out.println("--------"); //需求:输出数据5-1 for(int i=5; i>=1; i--) { System.out.println(i); } } }
案例二:求和
-
需求
求1-5之间的数据和,并把求和结果在控制台输出
-
代码实现
public class ForTest02 { public static void main(String[] args) { //求和的最终结果必须保存起来,需要定义一个变量,用于保存求和的结果,初始值为0 int sum = 0; //从1开始到5结束的数据,使用循环结构完成 for(int i=1; i<=5; i++) { //将反复进行的事情写入循环结构内部 // 此处反复进行的事情是将数据 i 加到用于保存最终求和的变量 sum 中 sum += i; /* sum += i; sum = sum + i; 第一次:sum = sum + i = 0 + 1 = 1; 第二次:sum = sum + i = 1 + 2 = 3; 第三次:sum = sum + i = 3 + 3 = 6; 第四次:sum = sum + i = 6 + 4 = 10; 第五次:sum = sum + i = 10 + 5 = 15; */ } //当循环执行完毕时,将最终数据打印出来 System.out.println("1-5之间的数据和是:" + sum); } } -
本题要点
- 今后遇到的需求中,如果带有求和二字,请立即联想到求和变量
- 求和变量的定义位置,必须在循环外部,如果在循环内部则计算出的数据将是错误的
案例三:偶数和
-
需求
求1-100之间的偶数和,并把求和结果在控制台输出
-
代码实现
public class ForTest03 { public static void main(String[] args) { //求和的最终结果必须保存起来,需要定义一个变量,用于保存求和的结果,初始值为0 int sum = 0; //对1-100的数据求和与1-5的数据求和几乎完全一样,仅仅是结束条件不同 for(int i=1; i<=100; i++) { //对1-100的偶数求和,需要对求和操作添加限制条件,判断是否是偶数 if(i%2 == 0) { sum += i; } } //当循环执行完毕时,将最终数据打印出来 System.out.println("1-100之间的偶数和是:" + sum); } }
案例四:水仙花
-
需求
在控制台输出所有的“水仙花数”
-
解释:什么是水仙花数
水仙花数,指的是一个三位数,个位、十位、百位的数字立方和等于原数
例如
153 3*3*3 + 5*5*5 + 1*1*1 = 153 -
思路分析
1. 获取所有的三位数,准备进行筛选,最小的三位数为100,最大的三位数为999,使用for循环获取 2. 获取每一个三位数的个位,十位,百位,做if语句判断是否是水仙花数 -
代码实现
public class ForTest04 { public static void main(String[] args) { //输出所有的水仙花数必然要使用到循环,遍历所有的三位数,三位数从100开始,到999结束 for(int i=100; i<1000; i++) { //在计算之前获取三位数中每个位上的值 int ge = i%10; int shi = i/10%10; int bai = i/10/10%10; //判定条件是将三位数中的每个数值取出来,计算立方和后与原始数字比较是否相等 if(ge*ge*ge + shi*shi*shi + bai*bai*bai == i) { //输出满足条件的数字就是水仙花数 System.out.println(i); } } } }
案例五:统计水仙花个数
-
需求
统计“水仙花数”一共有多少个,并在控制台输出个数
-
代码实现
public class ForTest05 { public static void main(String[] args) { //定义变量count,用于保存“水仙花数”的数量,初始值为0 int count = 0; //输出所有的水仙花数必然要使用到循环,遍历所有的三位数,三位数从100开始,到999结束 for(int i=100; i<1000; i++) { //在计算之前获取三位数中每个位上的值 int ge = i%10; int shi = i/10%10; int bai = i/10/10%10; //在判定水仙花数的过程中,满足条件不再输出,更改为修改count的值,使count+1 if(ge*ge*ge + shi*shi*shi + bai*bai*bai == i) { count++; } } //打印输出最终结果 System.out.println("水仙花共有:" + count + "个"); } } -
本题要点
- 今后如果需求带有统计xxx,请先想到计数器变量
- 计数器变量定义的位置,必须在循环外部
while循环
while结构
初始化语句;
while (条件判断语句) {
循环体语句;
条件控制语句;
}
while循环执行流程
①执行初始化语句
②执行条件判断语句,看其结果是true还是false
如果是false,循环结束
如果是true,继续执行
③执行循环体语句
④执行条件控制语句
⑤回到②继续
案例代码
public class WhileDemo {
public static void main(String[] args) {
//需求:在控制台输出5次"HelloWorld"
//for循环实现
for(int i=1; i<=5; i++) {
System.out.println("HelloWorld");
}
System.out.println("--------");
//while循环实现
int j = 1;
while(j<=5) {
System.out.println("HelloWorld");
j++;
}
}
}
while循环案例
-
需求
世界最高山峰是珠穆朗玛峰(8844.43米=8844430毫米),假如我有一张足够大的纸,它的厚度是0.1毫米。请问,我折叠多少次,可以折成珠穆朗玛峰的高度?
-
代码实现
public class WhileTest { public static void main(String[] args) { //定义一个计数器,初始值为0 int count = 0; //定义纸张厚度 double paper = 0.1; //定义珠穆朗玛峰的高度 int zf = 8844430; //因为要反复折叠,所以要使用循环,但是不知道折叠多少次,这种情况下更适合使用while循环 //折叠的过程中当纸张厚度大于珠峰就停止了,因此继续执行的要求是纸张厚度小于珠峰高度 while(paper <= zf) { //循环的执行过程中每次纸张折叠,纸张的厚度要加倍 paper *= 2; //在循环中执行累加,对应折叠了多少次 count++; } //打印计数器的值 System.out.println("需要折叠:" + count + "次"); } }
do...while循环
do...while循环格式
初始化语句;
do {
循环体语句;
条件控制语句;
}while(条件判断语句);
执行流程
① 执行初始化语句
② 执行循环体语句
③ 执行条件控制语句
④ 执行条件判断语句,看其结果是true还是false
如果是false,循环结束
如果是true,继续执行
⑤ 回到②继续
代码演示
public class DoWhileDemo {
public static void main(String[] args) {
//需求:在控制台输出5次"HelloWorld"
//for循环实现
for(int i=1; i<=5; i++) {
System.out.println("HelloWorld");
}
System.out.println("--------");
//do...while循环实现
int j = 1;
do {
System.out.println("HelloWorld");
j++;
}while(j<=5);
}
}
三种循环的区别
while和do...while
-
语法不同
while与do...while
-
执行流程不同
while先判断循环条件后进行循环体执行,do...while先执行循环体后进行条件判断
-
循环体执行次数不同
while循环体可能由于条件不满足一次都不执行,do..while循环体至少执行一次
-
使用场景不同
while就是根据条件决定循环体执行,跟循环条件无关必须至少执行
for循环和while的区别
-
变量作用域不同
for循环声明的变量只有当前循环可用,while在外声明可以直接使用
-
使用场景不同
已知次数的循环使用for循环,未知次数的循环使用while循环
死循环
- for(;😉{}
- while(true){}
- do {} while(true)
跳转控制语句
1 跳转控制语句(break)
跳出循环,结束循环
2 跳转控制语句(continue)
跳过本次循环,继续下次循环
3 结束跳转语句(return)
结束当前方法返回数据
4 注意事项
break和continue只能在循环中进行使用,单独使用无任何意义!!
//流程跳转语句
//使用关键字操作流程语句的跳转 完成对应的功能
public class Test10 {
public static void main(String[] args) {
//return 方法级别的结束
//会将当前方法后续代码全部结束 直接方法结束
for(int i=1;i<=100;i++){
if(i==5){
return;
//System.out.println(11111);
//return结束级别比break更高
}
System.out.print(i+" ");
}
System.out.println();
System.out.println("~~~~~~~~~~~~~~~~~");
//continue跳过本次循环中continue后续的代码
//继续进行下次循环
for(int i=1;i<=100;i++){
if(i==5){
continue;
}
System.out.print(i+" ");
}
System.out.println();
System.out.println("~~~~~~~~~~~~~~~~~~~~~");
//break 结束当前代码块后续代码(结束当前循环)
//当前代码块中 break之后的代码不会执行
for(int i=1;i<=100;i++){
if(i==5){
break;
//在break同级代码中之后不能书写其他代码
//因为break只要执行就会结束
//System.out.println(111);
}
System.out.print(i+" ");
}
System.out.println();
}
}
循环嵌套
1 循环嵌套概述
在循环中,继续定义循环
2 示例代码
public static void main(String[] args) {
//外循环控制小时的范围,内循环控制分钟的范围
for (int hour = 0; hour < 24; hour++) {
for (int minute = 0; minute < 60; minute++) {
System.out.println(hour + "时" + minute + "分");
}
System.out.println("--------");
}
}
3 结论
外循环执行一次,内循环执行一圈
4 嵌套循环案例
-
需求
使用嵌套for循环打印九九乘法表
-
思路分析
1. 定义外层循环控制有多少行 for(int i = 1 ; i <= 9 i ++) 2. 定义内层循环控制每一行输出多少个数据 for(int j = 1 ; j <= i ; j++) 3. 拼接输出 1 * 1 = 1 1 * 2 = 2 2 * 2 = 4 -
代码实现
public class TestJJ{ public static void main(String[] args){ for(int i = 1 ; i <= 9;i ++){ for(int j = 1 ; j <= i ; j++){ System.out.print(j + " * " + i + " = " + (i*j) +"\t"); } System.out.println(); } } }
Random
Random概述
Random类似Scanner,也是Java提供好的API,内部提供了产生随机数的功能
API后续课程详细讲解,现在可以简单理解为Java已经写好的代码
使用步骤
导入包
import java.util.Random;
创建对象
Random r = new Random();
产生随机数
int num = r.nextInt(10);
解释: 10代表的是一个范围,如果括号写10,产生的随机数就是0-9,括号写20,参数的随机数则是0-19
int num = r.nextInt(10)+1;
解释: 10代表的是一个范围,如果括号写10,产生的随机数就是0-9,现在外面加一就是把整体范围加一;本来是0-9;现在在外面 加一的话现在参数的随机数则是1-20
示例代码
import java.util.Random;
public class RandomDemo {
public static void main(String[] args) {
//创建对象
Random r = new Random();
//用循环获取10个随机数
for(int i=0; i<10; i++) {
//获取随机数
int number = r.nextInt(10);
System.out.println("number:" + number);
}
//需求:获取一个1-100之间的随机数
int x = r.nextInt(100) + 1;
System.out.println(x);
}
}
什么是数组
数组就是存储数据长度固定的容器,存储多个数据的数据类型要一致。
用于存储具有相同数据类型的容器称之为数组
特点:长度固定。存储类型相同
数组定义格式
格式一
数据类型[] 数组名;
示例:
int[] arr;
double[] arr;
char[] arr;
格式二
数据类型 数组名[];
示例:
int arr[];
double arr[];
char arr[];
数组初始化
数组动态初始化
什么是动态初始化
数组动态初始化就是只给定数组的长度,由系统给出默认初始化值
动态初始化格式
数据类型[] 数组名 = new 数据类型[数组长度];
int[] arr = new int[3];
动态初始化格式详解
-
等号左边
-
int:数组的数据类型
-
[]:代表这是一个数组
-
arr:代表数组的名称
-
-
等号右边
-
new:为数组开辟内存空间
-
int:数组的数据类型
-
[]:代表这是一个数组
-
3:代表数组的长度
-
数组静态初始化
什么是静态初始化
在创建数组时,直接将元素确定,由系统计算出数组的长度
静态初始化格式
-
完整版格式
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,...}; -
简化版格式
数据类型[] 数组名 = {元素1,元素2,...};
示例代码
public class ArrayDemo {
public static void main(String[] args) {
//定义数组
int[] arr = {1, 2, 3};
//输出数组名
System.out.println(arr);
//输出数组中的元素
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
}
}
数组元素访问
什么是索引
每一个存储到数组的元素,都会自动的拥有一个编号,从0开始。
这个自动编号称为数组索引(index),可以通过数组的索引访问到数组中的元素。
访问数组元素格式
数组名[索引];
示例代码
public class ArrayDemo {
public static void main(String[] args) {
int[] arr = new int[3];
//输出数组名
System.out.println(arr); //[I@880ec60
//输出数组中的元素
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
}
}
内存分配
内存概述
内存是计算机中的重要原件,临时存储区域,作用是运行程序。
我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的。
必须放进内存中才能运行,运行完毕后会清空内存。
Java虚拟机要运行程序,必须要对内存进行空间的分配和管理。
java中的内存分配
目前我们只需要记住三个内存,分别是:栈内存、堆内存、常量池
| 区域名称 | 作用 |
|---|---|
| 寄存器 | 给CPU使用,和我们开发无关。 |
| 本地方法栈 | JVM在使用操作系统功能的时候使用,和我们开发无关。 |
| 方法区 | 存储可以运行的class文件。 |
| 堆内存 | 存储对象或者数组,new来创建的,都存储在堆内存。 |
| 方法栈 | 方法运行时使用的内存,比如main方法运行,进入方法栈中执行。 |
| 常量池 | 分为运行时常量池与普通常量池,用于存储运行时使用的常量 |
数组操作的两个常见小问题
索引越界异常
-
出现原因
public class ArrayDemo { public static void main(String[] args) { int[] arr = new int[3]; System.out.println(arr[3]); } }数组长度为3,索引范围是0~2,但是我们却访问了一个3的索引。
程序运行后,将会抛出ArrayIndexOutOfBoundsException 数组越界异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码。
-
解决方案
将错误的索引修改为正确的索引范围即可!
空指针异常
-
出现原因
public class ArrayDemo { public static void main(String[] args) { int[] arr = new int[3]; //把null赋值给数组 arr = null; System.out.println(arr[0]); } }arr = null 这行代码,意味着变量arr将不会在保存数组的内存地址,也就不允许再操作数组了,因此运行的时候会抛出 NullPointerException 空指针异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码。
-
解决方案
给数组一个真正的堆内存空间引用即可!
数组案例
数组遍历
就是将数组中的每个元素分别获取出来,就是遍历。遍历也是数组操作中的基石。
public class ArrayTest01 {
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
System.out.println(arr[4]);
}
}
以上代码是可以将数组中每个元素全部遍历出来,但是如果数组元素非常多,这种写法肯定不行,因此我们需要改造成循环的写法。数组的索引是 0 到 lenght-1 ,可以作为循环的条件出现。
public class ArrayTest01 {
public static void main(String[] args) {
//定义数组
int[] arr = {11, 22, 33, 44, 55};
//使用通用的遍历格式
for(int x=0; x<arr.length; x++) {
System.out.println(arr[x]);
}
}
}
数组最值
数组最值就是从数组的所有元素中找出最大值或最小值
实现思路
- 定义变量,保存数组0索引上的元素
- 遍历数组,获取出数组中的每个元素
- 将遍历到的元素和保存数组0索引上值的变量进行比较
- 如果数组元素的值大于了变量的值,变量记录住新的值
- 数组循环遍历结束,变量保存的就是数组中的最大值
代码实现
public class ArrayTest02 {
public static void main(String[] args) {
//定义数组
int[] arr = {12, 45, 98, 73, 60};
//定义一个变量,用于保存最大值
//取数组中第一个数据作为变量的初始值
int max = arr[0];
//与数组中剩余的数据逐个比对,每次比对将最大值保存到变量中
for(int x=1; x<arr.length; x++) {
if(arr[x] > max) {
max = arr[x];
}
}
//循环结束后打印变量的值
System.out.println("max:" + max);
}
}
数组元素反转
数组中的元素颠倒顺序,例如原始数组为1,2,3,4,5,反转后的数组为5,4,3,2,1
实现思路
数组中的元素颠倒顺序,例如原始数组为1,2,3,4,5,反转后的数组为5,4,3,2,1
实现反转,就需要将数组最远端元素位置交换
定义两个变量,保存数组的最小索引和最大索引
两个索引上的元素交换位置
最小索引++,最大索引--,再次交换位置
最小索引超过了最大索引,数组反转操作结束
代码实现
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
/*
循环中定义变量min=0最小索引
max=arr.length‐1最大索引
min++,max‐‐
*/
for (int min = 0, max = arr.length ‐ 1; min <= max; min++, max‐‐) {
//利用第三方变量完成数组中的元素交换
int temp = arr[min];
arr[min] = arr[max];
arr[max] = temp;
}
// 反转后,遍历数组
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
维数组
什么是二维数组
二维数组其实就是一个元素为一维数组的数组
二维数组格式
格式一
数据类型[][] 变量名 = new 数据类型[m][n];
-
格式解释
-
m表示这个二维数组有多少个一维数组
-
n表示每一个一维数组的元素个数
-
-
举例
int[][] arr = new int[3][2]; 定义了一个二维数组arr 这个二维数组有3个一维数组,名称是arr[0],arr[1],arr[2] 每个一维数组有2个元素,可以通过arr[m][n]来获取 表示获取第m+1个一维数组的第n+1个元素
格式二
数据类型[][] 变量名 = new 数据类型[m][];
-
格式解释
-
m表示这个二维数组有多少个一维数组
-
这一次没有直接给出一维数组的元素个数,可以动态的给出
-
-
举例
int[][] arr = new int[3][]; // 第一个数组的元素个数为2 arr[0] = new int[2]; // 第一个数组的元素个数为3 arr[1] = new int[3] // 第一个数组的元素个数为1 arr[2] = new int[1];
格式三
标准版:
数据类型[][] 变量名 = new 数据类型[][]{{元素…},{元素…},{元素…}};
简化版:
数据类型[][] 变量名 = {{元素…},{元素…},{元素…}};
-
举例
int[][] arr = {{1,2,3},{4,5},{6}};
二维数组案例
-
需求
求公司年销售额求和
-
需求描述
某公司按照季度和月份统计的数据如下:单位(万元)
第一季度:22,66,44
第二季度:77,33,88
第三季度:25,45,65
第四季度:11,66,99 -
案例代码
public class ArrayCase { public static void main(String[] args) { // 定义二维数组 int[][] arr = {{22, 66, 44}, {77, 33, 88}, {25, 45, 65}, {11, 66, 99}}; // 求总和 int he = 0; for (int i = 0; i < arr.length; i++) { // 求每一季度的总销售额 int sum = 0; for (int j = 0; j < arr[i].length; j++) { sum += arr[i][j]; } // 将每一季度的总销售额累加到总和 he += sum; System.out.println("第" + (i + 1) + "季度的销售额是:" + sum); } System.out.println("总销售额: " + he); } }
数组练习
1、使用数组保存斐波那契数列
(头两个数为1 之后为前两项数据之和)1 1 2 3 5 8 13 21 34 55 89
public class Test7 {
public static void main(String[] args) {
//**1、使用数组保存斐波那契数列**
//(头两个数为1 之后为前两项数据之和)
//1 1 2 3 5 8 13 21 34 55 89
Scanner sc=new Scanner(System.in);
System.out.println("请输入数列个数");
//获取数列个数
int nextInt = sc.nextInt();
//创建对应长度的数组
int [] arr=new int[nextInt];
//遍历数组存入数据
for(int i=0;i<arr.length;i++){
if(i==0||i==1){
arr[i]=1;
}else{
arr[i]=arr[i-1]+arr[i-2];
}
}
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+"\t");
}
}
}
2、使用二维数组完成杨辉三角的保存
1
1 1
1 2 1
1 3 3 1
public class Test8 {
public static void main(String[] args) {
//**2、使用二维数组完成杨辉三角的保存**
Scanner sc=new Scanner(System.in);
System.out.println("请输入行数");
int [][] arr=new int [sc.nextInt()][];
for(int i=0;i<arr.length;i++){
arr[i]=new int[i+1];
for(int j=0;j<arr[i].length;j++){
if(j==0||j==arr[i].length-1){
arr[i][j]=1;
}else{
arr[i][j]=arr[i-1][j]+arr[i-1][j-1];
}
}
}
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
}
3、数组排序
public static void main(String[] args) {
//数组排序
int []arr={1,7,4,5,9,2,3,6,8};
System.out.print("原数组:");
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
System.out.println();
//思路:
//依次取出数据进行比较 将最值进行交换到起始或者最后
for(int i=0;i<arr.length;i++){
//依次取出索引跟之后的数据比较 进行交换
for(int j=i;j<arr.length;j++){
if(arr[i]>arr[j]){
int tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
}
}
System.out.print("排序后:");
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
}
}
方法概述
什么是方法
方法(method)是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集
减少代码冗余、提高代码复用性、增强程序可维护性与扩展性
方法基本使用
将打怪物发射炮弹重复的代码,抽取到方法中并使用
-
抽取代码
public static void fire() { System.out.println("准备发射5发炮弹"); System.out.println("发射第1发炮弹* * * *"); System.out.println("发射第2发炮弹* * * *"); System.out.println("发射第3发炮弹* * * *"); System.out.println("发射第4发炮弹* * * *"); System.out.println("发射第5发炮弹* * * *"); System.out.println("发射5发炮弹结束"); } -
在main方法中使用
public static void main(String[] args) { System.out.println("游戏开始..."); System.out.println("看到了一个怪物...血牙野猪..."); //调用方法,发射炮弹 fire(); System.out.println("...血牙野猪被打倒..."); } -
调用格式
方法名(); -
注意
-
方法必须先创建才可以使用,该过程成为方法定义
-
方法创建后并不是直接可以运行的,需要手动使用后,才执行,该过程成为方法调用
-
定义方法格式
修饰符 返回值类型 方法名(参数列表){
//代码省略...
return 结果;
}
-
修饰符: public static固定写法 -
返回值类型: 表示方法运行的结果的数据类型,方法执行后将结果返回到调用者 -
参数列表: 方法在运算过程中的未知数据,调用者调用方法时传递 -
return: 将方法执行后的结果带给调用者,方法执行到 return ,整体方法运行结束
小贴士:return 结果; 这里的"结果"在开发中,我们正确的叫法成为方法的返回值
方法案例
定义方法的两个明确
-
明确参数列表
该方法在完成一个功能时,需要的参数有几个,参数的类型是什么,需要在我们明确给出的。
-
明确返回值类型
方法的功能完成之后,是否有结果返回,如果有,使用return 将结果返回给调用者。
案例一
-
需求
在控制台打印10次HelloWorld
-
分析
-
明确参数列表
方法中打印出 HelloWorld 即可,没有计算结果,返回值类型 void
-
明确返回值
打印几次已经明确规定10次,参数不需要定义
-
-
代码实现
public class MethodDemo01 { public static void main(String[] args) { //调用方法printHelloWorld打印10次HelloWorld printHelloWorld(); } public static void printHelloWorld() { for (int i = 0; i < 10; i++) { System.out.println("HelloWorld"); } } }
案例二
-
需求
实现不定次数打印HelloWorld
-
分析
-
明确参数列表
方法中打印出 HelloWorld 即可,没有计算结果,返回值类型 void
-
明确返回值
打印几次不清楚,参数定义一个整型参数
-
-
代码实现
public class MethodDemo02 { public static void main(String[] args) { //调用方法printHelloWorld,传递整数 printHelloWorld(5); } /* 定义打印HelloWorld方法 返回值类型,计算没有结果 void 参数:不确定打印几次 */ public static void printHelloWorld(int n) { for (int i = 0; i < n; i++) { System.out.println("HelloWorld"); } } }
案例三
-
需求
定义方法实现两个整数的求和计算
-
分析
-
明确参数列表
计算哪两个整数的和,并不清楚,但可以确定是整数,参数列表可以定义两个int类型的
变量,由调用者调用方法时传递
-
明确返回值
方法计算的是整数的求和,结果也必然是个整数,返回值类型定义为int类型。
-
-
代码实现
public class MethodDemo03 { public static void main(String[] args) { // 调用方法getSum,传递两个整数,这里传递的实际数据又称为实际参数 // 并接收方法计算后的结果,返回值 int sum = getSum(5, 6); System.out.println(sum); } /* 定义计算两个整数和的方法 返回值类型,计算结果是int 参数:不确定数据求和,定义int参数.参数又称为形式参数 */ public static int getSum(int a, int b) { return a + b; } } -
流程图解

案例四
-
需求
定义方法实现比较两个整数是否相同
-
分析
-
明确参数列表
比较的两个整数不确定,所以默认定义两个int类型的参数。
-
明确返回值
比较整数,比较的结果只有两种可能,相同或不同,因此结果是布尔类型,比较的结果相
同为true。
-
-
代码实现
public class MethodDemo04 { public static void main(String[] args) { //调用方法compare,传递两个整数 //并接收方法计算后的结果,布尔值 boolean bool = compare(3, 8); System.out.println(bool); } /* 定义比较两个整数是否相同的方法 返回值类型,比较的结果布尔类型 参数:不确定参与比较的两个整数 */ public static boolean compare(int a, int b) { if (a == b) { return true; } else { return false; } } }
案例五
-
需求
定义方法实现:计算1+2+3...+100的和
-
分析
-
明确参数列表
需求中已知到计算的数据,没有未知的数据,不定义参数
-
明确返回值
1~100的求和,计算后必然还是整数,返回值类型是int
-
-
代码实现
public class MethodDemo05 { public static void main(String[] args) { //调用方法getSum //并接收方法计算后的结果,整数 int sum = getSum(); System.out.println(sum); } /* 定义计算1~100的求和方法 返回值类型,计算结果整数int 参数:没有不确定数据 */ public static int getSum() { //定义变量保存求和 int sum = 0; //从1开始循环,到100结束 for (int i = 1; i <= 100; i++) { sum = sum + i; } return sum; } }
方法小结
定义方法注意事项
-
定义位置:类中方法外,不能嵌套定义
-
方法必须先定义,再使用
-
void表示无返回值,可以省略return,也可以单独的书写return
-
不能在return后面写代码,return意味着方法结束,所有后面的代码记永远都不会执行,属于无效代码
-
定义方法时()中的参数,我们称之为:形式参数,在调用该方法时传递的参数,我们称之为:实际参数
调用方法三种形式
-
直接调用:直接写方法名调用public static void main(String[] args) { print(); } public static void print() { System.out.println("方法被调用"); } -
赋值调用:调用方法,在方法前面定义变量,接收方法返回值public static void main(String[] args) { int sum = getSum(5,6); System.out.println(sum); } public static int getSum(int a,int b) { return a + b; } -
输出语句调用:在输出语句中调用方法public static void main(String[] args) { System.out.println(getSum(5,6)); } public static int getSum(int a,int b) { return a + b; }-
注意事项
不能用输出语句调用void无返回值类型的方法。因为方法执行后没有结果,也就打印不出任何内容
public static void main(String[] args) { // 错误,不能输出语句调用void类型方法 System.out.println(printHello()); } public static void printHello() { System.out.println("Hello"); }
-
方法重载
方法重载概述
指在同一个类中,允许存在一个以上的同名方法,只要它们的参数列表不同即可,与修饰符和返回值类型无关。
参数列表:个数不同,数据类型不同,顺序不同。
重载方法调用:JVM通过方法的参数列表,调用不同的方法。
-
注意事项
* 重载仅对应方法的定义,与方法的调用无关,调用方式参照标准格式 * 重载仅针对同一个类中方法的名称与参数进行识别,与返回值无关,换句话说不能通过返回值来判定两个方法是否相互构成重载
//计算两个数据的和
public static int sum(int a,int b){
return a+b;
}
//方法的重载
//在同一个类中 方法名相同 参数列表不同 称之为发生了方法的重载
//有时在进行方法定义时 同一个功能由于参数传递不同可能需要书写多个方法
//需要定义多个方法名 但是功能相似 这个时候就可以使用方法的重载定义名称相同的不同方法
//参数列表不同——参数个数不同
public static int sum(int a,int b,int c){
return a+b+c;
}
//参数类型不同——参数个数相同 参数类型不同
public static double sum(double a,double b,double c){
return a+b+c;
}
//参数顺序不同——参数个数相同类型相同(两个以上)
//顺序不同不是参数变量顺不同 而是数据类型的顺序不同
public static double sum(int a,double b) {
return a+b;
}
public static double sum(double a,int b) {
return a+b;
}
//方法重载jvm调用过程
//顺序执行 执行对应方法时 会到方法栈中查找对应的方法名
//如果对应方法不存在则报错
//如果存在则进行判断 是否唯一
//如果存在多个同名方法 根据调用方法传入的参数个数进行匹配
//如果个数存在相同 依次根据参数的数据类型进行匹配
//在依次匹配时进行方法的选择
方法重载案例
案例一
-
需求
使用方法重载的思想,设计比较两个整数是否相同的方法,兼容全整数类型(byte,short,int,long)
-
思路
①定义比较两个数字的是否相同的方法compare()方法,参数选择两个int型参数
②定义对应的重载方法,变更对应的参数类型,参数变更为两个long型参数
③定义所有的重载方法,两个byte类型与两个short类型参数
④完成方法的调用,测试运行结果
-
代码实现
public class MethodTest1 { public static void main(String[] args) { //调用方法 System.out.println(compare(10, 20)); System.out.println(compare((byte) 10, (byte) 20)); System.out.println(compare((short) 10, (short) 20)); System.out.println(compare(10L, 20L)); } //int public static boolean compare(int a, int b) { System.out.println("int"); return a == b; } //byte public static boolean compare(byte a, byte b) { System.out.println("byte"); return a == b; } //short public static boolean compare(short a, short b) { System.out.println("short"); return a == b; } //long public static boolean compare(long a, long b) { System.out.println("long"); return a == b; } }
案例二
判断哪些方法是重载关系
public static void open(){}
public static void open(int a){}
public static void open(int a,int b){}
public static void open(double a,int b){}
public static void open(int a,double b){}
public static void OPEN(){}
public static void open(int i,int j){}
案例三
-
需求
模拟输出语句中的println方法的效果,传递什么类型的数据就输出什么类型的数据,只允许定义一个方法名println
-
代码实现
public class MethodTest2 { public static void println(byte a) { System.out.println(a); } public static void println(short a) { System.out.println(a); } public static void println(int a) { System.out.println(a); } public static void println(long a) { System.out.println(a); } public static void println(float a) { System.out.println(a); } public static void println(double a) { System.out.println(a); } public static void println(char a) { System.out.println(a); } public static void println(boolean a) { System.out.println(a); } public static void println(String a) { System.out.println(a); } }
方法的参数传递
方法参数传递基本类型
-
测试代码:
public class ArgsDemo01 { public static void main(String[] args) { int number = 100; System.out.println("调用change方法前:" + number); change(number); System.out.println("调用change方法后:" + number); } public static void change(int number) { number = 200; } } -
结论:
基本数据类型的参数,形式参数的改变,不影响实际参数
-
结论依据:
每个方法在栈内存中,都会有独立的栈空间,方法运行结束后就会弹栈消失

方法参数传递引用类型
-
测试代码
public class ArgsDemo02 { public static void main(String[] args) { int[] arr = {10, 20, 30}; System.out.println("调用change方法前:" + arr[1]); change(arr); System.out.println("调用change方法后:" + arr[1]); } public static void change(int[] arr) { arr[1] = 200; } } -
结论
对于引用类型的参数,形式参数的改变,影响实际参数的值
-
结论依据
引用数据类型的传参,传入的是地址值,内存中会造成两个引用指向同一个内存的效果,所以即使方法弹栈,堆内存中的数据也已经是改变后的结果

数组遍历
-
需求
设计一个方法用于数组遍历,要求遍历的结果是在一行上的。例如:[11, 22, 33, 44, 55]
-
思路
-
因为要求结果在一行上输出,所以这里需要在学习一个新的输出语句System.out.print(“内容”);
System.out.println(“内容”); 输出内容并换行
System.out.print(“内容”); 输出内容不换行
System.out.println(); 起到换行的作用 -
定义一个数组,用静态初始化完成数组元素初始化
-
定义一个方法,用数组遍历通用格式对数组进行遍历
-
用新的输出语句修改遍历操作
-
调用遍历方法
-
-
代码实现
public class MethodTest3 { public static void main(String[] args) { //定义一个数组,用静态初始化完成数组元素初始化 int[] arr = {11, 22, 33, 44, 55}; //调用方法 printArray(arr); } // 定义一个方法,用数组遍历通用格式对数组进行遍历 /* 两个明确: 返回值类型:void 参数:int[] arr */ public static void printArray(int[] arr) { System.out.print("["); for(int x=0; x<arr.length; x++) { if(x == arr.length-1) { System.out.print(arr[x]); } else { System.out.print(arr[x]+", "); } } System.out.println("]"); } }
数组最大值
-
需求
设计一个方法用于获取数组中元素的最大值
-
思路
① 定义一个数组,用静态初始化完成数组元素初始化
② 定义一个方法,用来获取数组中的最大值,最值的认知和讲解我们在数组中已经讲解过了
③ 调用获取最大值方法,用变量接收返回结果
④ 把结果输出在控制台
-
代码实现
public class MethodTest02 { public static void main(String[] args) { //定义一个数组,用静态初始化完成数组元素初始化 int[] arr = {12, 45, 98, 73, 60}; //调用获取最大值方法,用变量接收返回结果 int number = getMax(arr); //把结果输出在控制台 System.out.println("number:" + number); } //定义一个方法,用来获取数组中的最大值 /* 两个明确: 返回值类型:int 参数:int[] arr */ public static int getMax(int[] arr) { int max = arr[0]; for(int x=1; x<arr.length; x++) { if(arr[x] > max) { max = arr[x]; } } return max; } }

浙公网安备 33010602011771号