java基础语法

语言是工具,是基石,是规则,吾等站在巨人的肩膀上,得以望见远方,当一杯敬过往,一杯敬朝阳,一杯留给后人敬仰。

开发前言

java语言排行榜

2023年情况

Java语言概述

Java是一种高级编程语言,而且是面向对象的编程语言。

Java语言是美国Sun公司(Stanford University Network),在1995年推出的高级的编程语言。

Java语言共同创始人之一:詹姆斯·高斯林 (James Gosling),被称为“Java之父”

Java语言的版本:1.0-1.4,5.0…8.0…11…17…20

版本 发布日期 最终免费公开更新时间 最后延伸支持日期
JDK Beta 1995 - -
JDK 1.0 1996 年 1 月 - -
JDK 1.1 1997 年 2 月 - -
J2SE 1.2 1998 年 12 月 - -
J2SE 1.3 2000 年 5 月 - -
J2SE 1.4 2002 年 2 月 2008 年 10 月 2013 年 2 月
Java SE 5 2004 年 9 月 2009 年 11 月 2015 年 4 月
Java SE 6 2006 年 12 月 2013 年 4 月 2018 年 12 月
Java SE 7 2011 年 7 月 2015 年 4 月 2022 年 7 月
Java SE 8(LTS) 2014 年 3 月 Oracle 于 2019 年 1 月停止更新(商用)
Oracle 于 2020 年 12 月停止更新(非商用)
AdoptOpenJDK 于 2026 年 5 月或之前停止更新
Amazon Corretto 于 2023 年 6 月或之前停止更新
2030 年 12 月
Java SE 9 2017 年 9 月 OpenJDK 于 2018 年 3 月停止更新 -
Java SE 10 2018 年 3 月 OpenJDK 于 2018 年 9 月停止更新 -
Java SE 11 2018 年 9 月 Amazon Corretto 于 2024 年 8 月或之前停止更新
AdoptOpenJDK 于 2022 年 9 月停止更新
2026 年 9 月
Java SE 12 2019 年 3 月 OpenJDK 于 2019 年 9 月停止更新 -
Java SE 13 2019 年 9 月 OpenJDK 于 2020 年 3 月停止更新 -
Java SE 14 2020 年 3 月 OpenJDK 于 2020 年 9 月停止更新 -
Java SE 15 2020 年 9 月 OpenJDK 于 2023 年 3 月停止更新 -
Java SE 16 2021 年 3 月 OpenJDK 于 2021 年 9 月停止更新 -
Java SE 17 2021 年 9 月 2024年9月停止更新 2029 年 9 月
Java SE 18 2022 年 3 月 2022年9月停止更新 -
Java SE 19 2022 年 9 月 2023年3月停止更新 -
Java SE 20 2023 年 3 月 2023年9月停止更新 -
Java SE 21 2023 年 9 月 2028年9月停止更新 2031 年 9 月

目前我们学习使用的8.0

Java语言能做什么

Java语言主要应用在互联网程序的开发领域

  • web应用程序:电子商务网站、社交网站、在线银行、金融、物流、商城等
  • 桌面应用程序:视频播放器、游戏、图形编辑器等
  • 移动应用程序:Android应用程序等
  • 游戏:网页游戏、手机游戏等
  • 企业应用程序:管理系统等
  • 嵌入式系统:比如路由器、智能居家等

Java语言的跨平台实现原理

JVM: Java虚拟机,是专门用来运行Java程序的

平台: 指的就是操作系统,比如windows,linux,macos等

跨平台: 我们编写的一个Java程序,可以做多个操作系统上运行【一次编译,到处运行】

1.问题1

Java程序是跨平台的?

正确的,一次编译到处运行

2.问题2

JVM是跨平台的?

错误的,java的虚拟机本身不具备跨平台功能的。JVM是实现Java程序跨平台的基石,针对不同的操作系统提供不同版本的JVM,而程序在JVM中运行

3.问题3

Java程序的跨平台是依靠JVM的不跨平台实现的

正确的

image-20220727010926066

::: tip Coder 💬

Java开发的长项是服务器端编程,而服务器端操作系统,至今还是Unix-like操作系统的天下。各个操作系统虽然长得像,但还是有差异的。不具有跨平台特性的语言时就常常因为API的差异导致在更换服务器时总要进行大量的代码修改和测试。就有可能需要维护多份代码。无论开发成本、维护成本还是文档制作都要高出很多。

开发一般在Windows下开发,在Unix-like上运行。如果不能跨平台,那就要测试的时候都要先编译,然后挪到服务器上,然后再运行。麻烦低效。

不管从代码管理角度,更换服务器成本角度都是方便优秀的。

:::

JDK_JRE_JVM的组成和作用

JVM: Java虚拟机,是专门用来运行Java程序的,但是不能单独安装

JRE: Java运行环境,包含JVM(Java虚拟机,是专门用来运行Java程序的)和核心类库,jre=jvm+运行类库

JDK: Java开发工具包,包含JRE和开发工具,jdk=jre+编译器等开发工具

三者关系: JDK > JRE > JVM

image-20200420095512929

Java语言开发环境搭建

JDK安装

显示文件扩展名

image-20220523093753992

jdk的下载和安装

1.注意操作系统是windows,linux,MacOS

2.注意操作系统的位数是32位还是64位

3.安装java相关软件的时候: 安装路径中不允许出现中文和空格

常用DOS命令的使用

如何进入DOS命令操作窗口?

1.开始/命令提示符

2.开始/搜索程序和文件 输入cmd

3.windows+R->输入cmd

4.窗口空白处/按住shift键 + 鼠标右键单击/在此处开命令窗口

操作 说明
盘符名称: 盘符切换。E: +回车,表示切换到E盘
dir 查看当前路径下的内容
cd 目录1\目录2... 进入目录
cd .. 回退到上级目录
cd \ 回退到盘符目录
cls 清屏
exit 退出命令提示符窗口

环境变量JAVA_HOME的配置

image-20220727011825209

image-20230616224633304

给Java配置环境变量的意义/目的/作用?

DOS查询软件先在当前路径查找,再在Path中查找。

配置Java环境变量让我们可以在任意路径下运行java开发的相关工具(javac: 编译工具,java: 运行工具)

变量名一定要叫JAVA_HOME吗?

不一定,但是建议叫JAVA_HOME,后续要使用的软件,只会识别该名称。比如tomcat要识别这个变量用到jdk的类库

为什么java_home不直接带上bin?

因为java不只用到 /bin 下的目录,很多程序还需要用到 java_home 目录下的其它东西

java文件区分大小写,为什么dos执行javac编译成功?

windows不区分大小写,所以编译可以

找不到或无法加载主类?

classpath不要配

HelloWorld入门程序

之所以写的这么细,只是为了方便理解图形化工具IDEA帮我们做了什么

程序开发的步骤

1.源程序:

  • 源程序是程序员编写的,程序员自己可以看得懂的程序(字母,数字,其他符号),本质就是一个文本文件,但是扩展名不是.txt,而是.java

2.生产JVM可以执行的字节码(.class)文件

  • JVM: 叫做Java虚拟机,是专门用来运行Java程序的
  • 但是JVM是一个二货,只能识别0和1,而存储0和1的文件叫做字节码文件(.class文件)
  • 如何把源文件(程序)翻译成JVM能够执行的字节码文件(程序)呢?
  • 使用javac命令(编译命令)
  • 使用格式: javac 文件名.java
  • 编译HelloWorld.java源文件: javac HelloWorld.java
  • 生成一个字节码文件: HelloWorld.class

3.把字节码文件交给JVM执行

  • 不管是源文件(程序)还是字节码文件(程序)都存储在硬盘中?
  • 不会自动执行,如何把字节码文件交给JVM执行呢?
    • 使用java命令(运行命令),使用格式: java 文件名,java HelloWorld

HelloWorld案例的编写编译运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
1.编写源文件
创建一个名称为HelloWorld.txt的文本文件,把扩展名修改为.java
打开HelloWorld.java源文件,输入以下内容,并保存(ctrl+s)
public class HelloWorld {
public static void main(String[] args){
System.out.println("HelloWorld");
}
}

2.编译: javac命令
根据.java源文件生产对应的.class文件(字节码文件)
使用javac命令的格式:
javac 文件名.java
javac HelloWorld.java

注意:
(1)保证当前路径下javac命令可以使用
(2)保证当前路径下有要进行编译的源(.java)文件
(3)使用编译javac命令时,文件名后面必须写扩展名.java

3.运行: java命令
把字节码(.class)文件交给jvm执行
使用java命令的格式:
java 文件名
java HelloWorld
注意:
(1)保证当前路径下java命令可以使用
(2)保证当前路径下有要进行运行的字节码(.class)文件
(3)使用运行java命令时,文件名后面不能写扩展名.class

HelloWorld案例的常见问题

  • 非法字符问题。Java中的符号都是英文格式的。
  • 大小写问题。Java语言对大小写敏感(区分大小写)。
  • 在系统中显示文件的扩展名,避免出现HelloWorld.java.txt文件。
  • 编译命令后的java文件名需要带文件后缀.java
  • 运行命令后的class文件名(类名)不带文件后缀.class
  • 不要把main写成mian

注释和关键字和保留字和补码

注释

::: tip Coder 💬

写代码和注释的第一目的是帮助人理解代码,理解作者的意图。

所以优秀的代码本身就有自说明功能,只有在代码本身无法清晰地阐述作者的意图时,才考虑写注释。

也即是:注释应该表达“我的代码为什么要这么做?”,而不是表达“我的代码做了什么?”

:::

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1.概念:
用来解释说明程序的文字,是给程序员看的,不会影响程序的编译和运行效率。
2.分类:
(1)当行注释: // 只能写一行内容
(2)多行注释: /* 可以写多行(1行,2行...)内容 */
(3)文档注释: /** 可以写多行(1行,2行...)内容 */

//这里是定义一个类,类的名字叫做Demo01ZhuShi,
//而且文件名必须和类的名字保持一模一样,public class 目前是固定写法,目前记住,后面讲解
public class Demo01ZhuShi {
/*
这里是定义main方法,public static void main(String[] args)是固定写法
main方法是程序的入口
*/
public static void main(String[] args){
/*
这是一个输出语句,用来向控制台输出显示内容的,
()中的""里面的内容会被输出显示到控制台上
*/
System.out.println("zhushi....");
}
}

关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
关键字:
1.概念: 是指在程序中,Java已经定义好的单词,具有特殊含义和特殊使用方式。
具体的哪些单词是关键字,它们的特殊含义和用法是什么?
要求能够辨识出程序中的关键字

2.特点:
(1)所有的字母都是小写的
(2)高级编辑器中彩色显示

3.说出以下程序中的关键字:
public class static void
*/
public class Demo02GuanJianZi {
public static void main(String[] args){
System.out.println("guanjianzi....");
}
}

保留字

日后能够会提升为关键字,即不能用作标识符。如,goto,const.

源码反码补码

所有数据的运算都是采用补码进行的(方便处理负数)

原码、反码和补码都是表示有符号整数的编码方法。

  • 正数(符号位/最高位为0),正数原反补相同
  • 负数(符号位为1),原码的数值位表示数值的绝对值,反码是原码数值位按位取反,补码是反码加1
1
2
3
4
5
6
7
8
9
10
11
12
13
已知原码->求补码: 
0b1 0110100(原码)
1 1001011(反码):取反
0 0000001(+1
---------------
1 1001100(补码)
已知补码->求原码:
0b1 1101110(补码)
1 1101110(补码)
0 0000001(-1
----------------
1 1101101(反码)
1 0010010(原码)

从原反补的角度理解为什么130强转为byte后是-126

1
2
3
4
5
6
7
8
9
10
11
12
13
14
byte b = (byte)130; // -126
整数130:默认为int,占用4个字节,也就是4组8个二进制位
00000000 00000000 00000000 10000010
强转到byte,4个字节强转为1个字节,砍掉前3组8位
10000010
根据运算后的补码,反向推原码
补码 -> 反码: 末尾 - 1
10000010
-1
--------
10000001
反码 -> 原码: 符号位不变,其余数值逐位取反
11111110
8421码计算得到: 这个位-126

常量

常量的概念和分类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
数学中有常数的概念:
y = x + 5; // 数字5是一个常数,其值不可以发生改变
b = a + 5.5;//数字5.5是一个常数,其值不可以发生改变

数学中对常数进行了分类:
比如:
数字5 是一个整数常数,其值不可以发生改变
数字5.5是一个小数数常数,其值不可以发生改变

数学中的常数,对应到java中叫常量,数学中的常数有分类,java中的常量也有分类,而且比数学中的分类更加丰富

1.概念: 在程序的执行过程中,其值不可以发生改变的量
2.分类:
(1)整数常量: 100 200
(2)小数常量: 5.5 7.7
(3)字符常量:
java中规定字符常量必须使用单引号''引起来,而且单引号''中只能写一个字符(不能不写,也不能写2个以上)
举例:
A: 'a' 正确的
B: ' ' 里面有一个空格 正确的
C: '好' 正确的

D: '' 里面什么都没有写 错误的(编译器会报错)
E: 'ab' 错误的
F: '女子' 错误的
(4)布尔常量:只有两个值truefalse
true: 表示肯定的,对的,是的,正确的,成立的
false:表示否定的,错的,不是的,却无的,不成立的
(5)字符串常量:
java中规定字符串常量必须使用双引号""引起来,而且双引号""中可以写多个字符(0个,1个,2个....)
举例:
A: "a" 正确的
B: "" 里面什么都没有写 正确的
C: " " 里面有一个空格 正确的
D: "ab" 正确的
E: "好" 正确的
F: "女子" 正确的

(6)空常量: null
null 不能直接被打印到控制台

快捷键: ctrl + d 复制一行

System.out.println(xxx);//把xxx输出到控制台,并换行
System.out.print(xxx);//把xxx输出到控制台,不换行

打印不同类型的常量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class Demo03ChangLiang {
public static void main(String[] args){
//(1)整数常量: 100 200
System.out.println(100);
System.out.println(200);

//(2)小数常量: 5.5 7.7
System.out.println(5.5);
System.out.println(7.7);

//(3)字符常量:
System.out.println('a');
//System.out.println('');//错误的: ''不能没有字符
System.out.println(' ');//正确的: ' '有一个空格
System.out.println('好');//正确的
//System.out.println('女子');//错误的: '女子'不能写2个及以上的字符

//(4)字符串常量
System.out.println("a");
System.out.println("");
System.out.println(" ");
System.out.println("ab");
System.out.println("好想你");
System.out.println("女子");

//(5)布尔常量
System.out.println(true);
System.out.println(false);

//(6)空常量
//System.out.println(null);//错误: 不能直接打印空常量null

char[] chars={'a','b','c'};
System.out.println(chars); // abc
int[] ints={1,2,3};
System.out.println(ints);// [I@282ba1e
//char[]可以直接打印内容,因为println底层实现了
//而int[]只能打印出数组地址,因为底层没有实现
//ctrl+p可以查看print方法接收参数的详情
}
}

示例

1
2
3
4
static final double PI = 3.14;
常量不是PI,而3.14,PI是标识符,是变量。常量是值。不要理解错了。
这里final修饰的变量为常量,指的是变量PI指向常量的值不能改变了。故称为常量,不要混淆了。
备注:是因为基本数据类型,所以值不会变了,如果是引用类型,只是引用指向的地址值不变,内容可以变。

进制与字节

进制及转换

进制

1
2
3
4
5
6
进制的概念:逢几进一就叫做几进制
进制的分类:
十进制: 逢十进一 每位的数字0-9
二进制: 逢二进一 每位的数字0-1
八进制: 逢八进一 每位的数字0-7
十六进制: 逢十六进一 每位的数字0-9,10(A/a),11(B/b),12(C/c),13(D/d),14(E/e),15(F/f)

转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1.十进制转十进制
(十进制数字的每一位(从右向做)上隐藏了一个10的多少次方,第1位是100次方,第2位是101次方...):
十进制数字1234(x^y: x的y次方):
1234 = 4 + 30 + 200 + 1000
= 4*10^0 + 3*10^1 + 2*10^2 + 1*10^3

2.二进制转十进制(8421编码): (系数*基数的权次幂)
二进制数字10010:
10010 = 1 * 2 ^ 4 + 0 * 2 ^ 3 + 0 * 2 ^ 2 + 1 * 2 ^ 1 + 0 * 2 ^ 0 = 18
(二进制数字的每一位(从右向做)上隐藏了一个2的多少次方,第1位是20次方,第2位是21次方...):
1101 = 1*2^0 + 0*2^1 + 1*2^2 + 1*2^3
= 1*1 + 0*2 + 1*4 + 1*8
= 1 + 0 + 4 + 8
= 13

1111 = 1*2^0 + 1*2^1 + 1*2^2 + 1*2^3
= 1*1 + 1*2 + 1*4 + 1*8
= 1 + 2 + 4 + 8
= 15


3.十进制转二进制: 除以2取余数,倒过来写(除积倒取余)
十进制的13转换成二进制: 1101
十进制的75转换成二进制: 1001011

十进制转二进制图解

十进制转2进制:除以2取余数,倒过来写

image-20220727012734608

计算机中的存储单位

2的10次方就是1024

1
2
3
4
5
6
7
8
9
10
11
12
13
1.位(bit): 计算机中存储一个数字0或者1所占用的空间   简写成b
2.字节(Byte): 8个bit(比特,二进制位)0000-0000表示为1byte(字节,1B),简写成B
字节是我们常见的计算机中最小存储单元(右键文件属性,可以看到xxx字节)。
1B = 8b
1024B = 1KB
1024KB = 1MB
1024MB = 1GB
1024GB = 1TB
1024TB = 1PB
....

务必记住:
1个字节是8

变量和数据类型

变量概念及分类

程序是运行在内存的,数据在内存中通过变量存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
数学中有个常数的概念:
y = x + 10; //整数数字10是不可以发生变化的
b = a + 6.6; //小数数字6.6是不可以发生变化的

数学中的数字(常量)是有分类的,对应java中的常量也是有分类的

x,y是可以发生变化的
x: 2 y: 12
x: 6 y: 16

x,y中的数据是可以发生变化的,而且x,y内部的数据也是有类型(整数)


a,b是可以发生变化的
a: 2.2 b: 8.8
a: 3.3 b: 9.9
b,b中的数据是可以发生变化的,而且a,b内部的数据也是有类型(小数)

像x,y,a,b 这样东西,里面的数据是可以发生变化的,而且数据是有类型的,我们把这样的东西称为变量(容器: 里面只能放一个数据)

变量为什么要有这么多的分类: 不同的分类,占用的字节数不同,取值范围就不同,使用的场景也就不同

1.变量概念: 在程序的执行过程中,其值可以在一定范围内发生改变的量
2.分类:
(1)整数
byte 1个字节 -128127
short 2个字节 正负3万多
int 4个字节 正负21亿 整数默认int类型
long 8个字节 大概19位数字 表示long类型数据后面需要加L/l

(2)小数
float 4个字节 表示float数据后面需要加F/f
注意: 虽然float4个字节,但是由于采用科学计数法,取值范围远远超过long
double 8个字节 小数默认double类型

(3)字符:
char 2个字节 0-65535
(4)布尔:
boolean 1个字节 取值为true或者false

1
2
3
4
5
6
7
8
9
10
11
12
// 两个变量互换值
temp = x;
x = y ;
y = temp;

a = a + b;
b = a - b;
a = a - b;

a = a ^ b;
b = a ^ b;
a = a ^ b;

注意点:

  • 变量在使用之前必须要赋值
  • 留意float和long类型变量定义要加后缀,float加F,long加L
  • 因为整数默认int,想表示一个数为long要加L,
  • 因为浮点型默认double,想表示一个数为float要加F
  • 引用数据类型(类,数组,接口,字符串,lambda,枚举enum,注解)
  • 基本数据类型(4类8种:整数,浮点数,字符,布尔): byte,short,int,long; float,double; char; boolean;
    • 浮点型是近似值而非精确值,4个字节的float要比8个字节的long大。
    • boolean为一个字节理论上只需要1/8字节(一位bit就可以决定true/false),但是java中没有明确指定它的大小。
    • int a = 1; byte b = 2;int j = b + a; // b自动补充3个字节后计算
    • byte,short,char运算时自动提升为int
    • 引用数据类型==比较的是地址值
    • 字符串new的在堆中,直接双引号写的在堆中的常量池里

变量定义格式图解分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
变量的理解:
1.变量的本质就是内存中的一块空间,空间的大小由数据类型决定
2.要想找到变量对应的内存空间的数据,需要给变量对应的内存空间起个名字,叫做变量名称
3.变量对应的内存空间中必须有数据才能使用,这种向变量内存空间中,存储数据的过程叫做初始化或者赋值

变量的定义格式一(先挖坑,然后种萝卜):
数据类型 变量名称;//先挖坑
变量名称 = 数据值;//再种萝卜

变量的定义格式二(挖坑,同时种萝卜):
数据类型 变量名称 = 数据值;//挖坑,同时种萝卜

变量的定义格式三(先挖多个坑,然后分别向每个坑中种萝卜):
数据类型 变量名称1,变量名称2,变量名称3;//先挖多个坑
变量名称1 = 数据值1;//向第一个坑中种萝卜
变量名称2 = 数据值2;//向第二个坑中种萝卜
变量名称3 = 数据值3;//向第三个坑中种萝卜

变量的定义格式四(挖多个坑,同时分别向每个坑中种萝卜):
数据类型 变量名称1 = 数据值1,变量名称2 = 数据值2,变量名称3 =数据值3 ;

图解:

1
2
3
4
5
6
7
内存可以理解为田地,变量理解为萝卜坑
1.一个萝卜一个坑
2.大萝卜放大坑
3.小萝卜放小坑
Java 程序中是没有萝卜的,有的数据
1.整数的萝卜放整数的坑中
2.小数的萝卜放小数的坑中

程序在JVM(内存)中运行

image-20220727013205917

定义8种变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class Demo01BianLiang {
public static void main(String[] args){
/*
变量的定义格式一(先挖坑,然后种萝卜):
数据类型 变量名称;//先挖坑
变量名称 = 数据值;//再种萝卜
*/
byte a;//挖了一个byte类型(1个字节)的坑,给这个坑起个名字叫a
a = 66;//把数字66存储到byte类型的坑a中
System.out.println(a);//打印byte类型(1个字节)的坑a中的内容: 66
a = 88;//把数字88存储到byte类型的坑a中,原有的数据66将被替换
System.out.println(a);//打印byte类型(1个字节)的坑a中的内容: 88

/*
变量的定义格式二(挖坑,同时种萝卜):
数据类型 变量名称 = 数据值;//挖坑,同时种萝卜
*/
short b = 100;//挖了一个short类型(2个字节)的坑,给这个坑起个名字叫b,同时向这个坑中存储数字100

System.out.println(b);//打印short类型(2个字节)的坑b中的内容: 100

/*
变量的定义格式三(先挖多个坑,然后分别向每个坑中种萝卜):
数据类型 变量名称1,变量名称2,变量名称3;//先挖多个坑
变量名称1 = 数据值1;//向第一个坑中种萝卜
变量名称2 = 数据值2;//向第二个坑中种萝卜
变量名称3 = 数据值3;//向第三个坑中种萝卜
*/
int c,d,e;//挖了三个int类型(4个字节)的坑,给每个坑分别起名为c,d,e

c = 200;//把数字200存储到int类型的坑c中
d = 300;//把数字300存储到int类型的坑d中
e = 500;//把数字500存储到int类型的坑e中

System.out.println(c);//打印int类型(4个字节)的坑c中的内容: 200
System.out.println(d);//打印int类型(4个字节)的坑d中的内容: 300
System.out.println(e);//打印int类型(4个字节)的坑e中的内容: 500

/*
变量的定义格式四(挖多个坑,同时分别向每个坑中种萝卜):
数据类型 变量名称1 = 数据值1,变量名称2 = 数据值2,变量名称3 =数据值3 ;
*/
//挖了三个long类型的坑,名字分别叫做f,g,h
//同时把600L存储到坑f中
//同时把700L存储到坑g中
//同时把800L存储到坑h中
long f = 600L,g = 700L,h = 800L;

System.out.println(f);//打印long类型(8个字节)的坑f中的内容: 600
System.out.println(g);//打印long类型(8个字节)的坑g中的内容: 700
System.out.println(h);//打印long类型(8个字节)的坑h中的内容: 800

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class Demo02BianLiang {
public static void main(String[] args){
//float类型
//定义float类型变量a,并初始化
//大萝卜不能直接存储到小坑中
//float a = 6.6;//错误: 6.6默认是double类型,占8个字节,不能存储到4个字节的float变量中

float a = 6.6F;
System.out.println(a);//打印变量a中的内容

//double类型
//定义double类型变量b,并初始化
double b = 8.8;
System.out.println(b);//打印变量b中的内容

//char类型
//定义char类型变量c1,并初始化
char c1 = 'a';
System.out.println(c1);//打印变量c1中的内容

//char c2 = '';//错误: ''中不能不写字符
//System.out.println(c2);//打印变量c2中的内容

//char c3 = 'ab';//错误: ''中不能写2个及以上的字符
//System.out.println(c3);//打印变量c3中的内容

//boolean类型: 只能存储true或者false
//定义boolean类型变量d1,并初始化
boolean d1 = true;
System.out.println(d1);//打印变量d1中的内容

d1 = false;//把false存储到变量d1中,原有的数据将被替换

System.out.println(d1);//打印变量d1中的内容

//d1 = 100;//错误: 数据类型不匹配
//System.out.println(d1);//打印变量d1中的内容


}
}

变量的注意事项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
变量定义的注意事项:
1.变量名称:在同一个大括号范围内,变量的名字不可以相同。
2.变量赋值:定义的变量,不赋值不能使用。
3.定义long类型的变量时,需要在整数的后面加L(大小写均可,建议大写)。
因为整数默认是int类型,整数太大可能超出int范围。

4.定义float类型的变量时,需要在小数的后面加F(大小写均可,建议大写)。
因为浮点数的默认类型是doubledouble的取值范围是大于float的,类型不兼容。

public class Demo03BianLiangNotice {
public static void main(String[] args){

//定义int变量a,并初始化
int a = 100;
System.out.println(a);

//错误: 不能在同一个区域({}),定义同名的变量
//int a = 200;
//System.out.println(a);

//定义int变量b,未赋值
int b;
//System.out.println(b);//错误: b中没有值,不能使用

b = 200;//把数字200赋值给变量b
System.out.println(b);

//long c = 6000000000;//错误: 6000000000(60亿)默认是int类型,但是大小已经远远超过int的取值范围(正负21亿)了
//System.out.println(c);

long d = 6000000000L;//6000000000L: 是long类型的数据
System.out.println(d);

//错误: 大萝卜不能直接放入小坑中
//float e = 6.6;//错误: 6.6默认是double类型,占8个字节,不能赋值给4个字节的float变量e
//System.out.println(e);

float f = 6.6F;//6.6F: 是float类型的数据
System.out.println(f);
}
}

标识符的含义及注意事项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
标识符:
1.概念: 程序中起名字的地方(类名,方法名称,变量名)
2.命名规则: 硬 性 要 求
标识符可以包含 英文字母26个(区分大小写) 、 0-9数字 、 $(美元符号) 和 _(下划线) 。
标识符不能以数字开头。
标识符不能是关键字。
3.命名规范: 软 性 建 议
类名规范:首字母大写,后面每个单词首字母大写(大驼峰式)。
Demo01BianLiang
Demo02BianLiang
Demo03BianLiangNotice
Demo04BiaoShiFu

方法名规范: 首字母小写,后面每个单词首字母大写(小驼峰式)。
getMin(...){...}
getMax(...){...}

变量名规范:首字母小写,后面每个单词首字母大写(小驼峰式)。
num
value
maxValue
public class Demo04BiaoShiFu {
public static void main(String[] args){
int b2;//正确
//int b*2;//错误: 不能包含*

//int 2b;//错误: 不能以数字开头

//int public;//错误: 不能是关键字。

//按照小驼峰规则,定义变量
int ageOfMyGirlFriend = 18;
System.out.println(ageOfMyGirlFriend);
}
}

数据类型转换

自动类型转换【从小到大自动】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Java程序中要求参与的计算的数据,必须要保证数据类型的一致性,如果数据类型不一致将发生类型的转换。
int + int
int + long ==> long + long (把int转换成long: 从小到大,自动类型转换,不需要代码的干预)
int + long ==> int + int (把long转成int: 从大到小,强制类型转换,必须手动代码完成)


1.自动类型转换概念:
也叫隐式转换,取值范围小的数据或者变量可以直接赋值给取值范围大的变量(小萝卜可以直接放入大坑中)

2.特点:
(1)自动类型转换是自动完成的,不需要代码的干预
(2)byte/short/char类型数据,只要参加运算会自动转换为int类型(哪怕是2byte变量相加,也会提升成int计算)
(3)转换链路:byteshortchar-->int-->long-->float-->double
举例:
有一个byte类型(1个字节)的数字5: 00000101
byte类型自动类型转换成short类型(2个字节):
在左侧补充1个字节的0,因为左侧补充的都是0,对原有数据是没有影响的,仍然是5
00000000 00000101

byte类型自动类型转换成int类型(4个字节):
在左侧补充3个字节的0,因为左侧补充的都是0,对原有数据是没有影响的,仍然是5
00000000 00000000 00000000 00000101

byte类型自动类型转换成long类型(8个字节):
在左侧补充7个字节的0,因为左侧补充的都是0,对原有数据是没有影响的,仍然是5
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000101

总结:
根据需求,在数据前面补充若干字节的0,因为补充的都是0,对原有数据大小是没有影响的(打肿脸充胖子)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Demo05Convert {
public static void main(String[] args){
int i = 1;
byte b = 2;
/*
b是byte类型,i是int类型,运算时类型不一致,会发生自动类型转换
byte类型(1个字节)的b会自动转换成int类型(4个字节):在byte类型的b左侧补充3个字节的0

最终变成了两个int数据相加,结果是int类型(占用4个字节),不能直接赋值给左侧的byte类型的变量x,占用1个字节

大萝卜不能直接放入小坑中
*/
//byte x = b + i;
//System.out.println(x);

/*
b是byte类型,i是int类型,运算时类型不一致,会发生自动类型转换
byte类型(1个字节)的b会自动转换成int类型(4个字节):在byte类型的b左侧补充3个字节的0

最终变成了两个int数据相加,结果是int类型(占用4个字节),可以直接赋值给左侧的int类型的变量y,占用4个字节

大萝卜可以直接放入大坑中
*/
int y = b + i;
System.out.println(y);//3
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Demo06Convert {
public static void main(String[] args){
int i = 1;
double d = 2.5;
/*
i是int类型,d是double类型,运算时类型不一致,会发生自动类型转换
int类型(4个字节)的i会自动转换成double类型(8个字节): 最终效果就是在整数后面添加.0 比如: 1变成1.0

最终变成了两个double数据相加,结果是double类型(占用8个字节),不能直接赋值给左侧的int类型的变量x,占用4个字节

大萝卜不能直接放入小坑中
*/
//int x = i + d;
//System.out.println(x);

/*
i是int类型,d是double类型,运算时类型不一致,会发生自动类型转换
int类型(4个字节)的i会自动转换成double类型(8个字节): 最终效果就是在整数后面添加.0 比如: 1变成1.0

最终变成了两个double数据相加,结果是double类型(占用8个字节),可以直接赋值给左侧的double类型的变量y,占用8个字节

大萝卜可以直接放入大坑中
*/
double y = i + d;
System.out.println(y);
}
}

强制类型转换【从大到小强制】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
1.强制类型转换概念:	
取值范围大的数据或者变量不能直接赋值给取值范围小的变量(大萝卜不能直接放入小坑中)
解决方案:
(1)把坑变大
(2)把萝卜变小(强制类型转换)

2.格式:
转后类型 变量名称 = (转后类型)转前数据或者变量;
long类型(8个字节)的数字5:
long num = 5L;
long类型强制类型转换成int类型(4个字节):
int a = (int)num;//把num中的数据强制类型转换成int类型,并把结果赋值给int变量a

举例:
有一个long类型(8个字节)的数字5:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000101

long类型强制类型转换成int类型(4个字节):
砍掉左侧的四个字节的内容,因为砍掉的都是数字0,所以对最终的结果数据没有影响仍然是5
00000000 00000000 00000000 00000101


long类型强制类型转换成short类型(2个字节):
砍掉左侧的六个字节的内容,因为砍掉的都是数字0,所以对最终的结果数据没有影响仍然是5
00000000 00000101

long类型强制类型转换成byte类型(1个字节):
砍掉左侧的七个字节的内容,因为砍掉的都是数字0,所以对最终的结果数据没有影响仍然是5
00000101

总结:
根据需求,砍掉数据左侧的若干字节的数据,只要砍掉的都是0,对原数据没有影响
但是只要砍掉的数据中包含1,就会对原数据产生影响(可能会损失精度)

精度损失:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Demo07Convert {
public static void main(String[] args){
double d = 1.5;
/*
左侧d是double类型(占8个字节),右侧的int类型的变量x(占4个字节)
相当于: 左侧是较大的数据,右侧的变量比较小
大萝卜不能直接放入小坑中
*/
//int x = d;
//System.out.println(x);
/*
左侧d是double类型(占8个字节),右侧的int类型的变量x(占4个字节)
double数据是不能直接赋值给int变量的: 大萝卜不能直接放入小坑中
但是进行了强制类型转换,把double数据强制转换成int数据

double强制类型转换成int: 直接把小数部分干掉,会损失精度
*/

int y = (int)d;

System.out.println(y);
}
}

数据溢出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Demo08Convert {
public static void main(String[] args){
short s = 1;
/*
s是short类型,1是int类型,运算时类型不一致,会发生自动类型转换
short类型(2个字节)的s会自动转换成int类型(4个字节):在short类型的s左侧补充2个字节的0

最终变成了两个int数据相加,结果是int类型(占用4个字节),不能直接赋值给左侧的short类型的变量s,占用2个字节

大萝卜不能直接放入小坑中
*/
//s = s + 1;
//System.out.println(s);


/*
s是short类型,1是int类型,运算时类型不一致,会发生自动类型转换
short类型(2个字节)的s会自动转换成int类型(4个字节):在short类型的s左侧补充2个字节的0

最终变成了两个int数据相加,结果是int类型(占用4个字节),不能直接赋值给左侧的short类型的变量s,占用2个字节

但是在赋值之前把int类型的结果,强制转换成short类型(砍掉左侧的2个字节的内容),
由于砍掉的2个字节都是0,所以最终的结果没有影响,仍然是2

把萝卜变小
*/
s = (short)(s + 1);
System.out.println(s);
}
}

图解(其它案例):

image-20200508120946828

ASCII码表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
计算机是一个二货,只能存储01,所以存储到计算机中的所有内容都会转换成01进行存储
所以我们在计算机中存储的字符也不例外,也需要把字符转换成01进行存储
问题: 如何把字符转换成01呢?
通过ASCII编码表: 存储字符和数字对应关系的一张表格

存储字符时:需要查找ASC码表,找到字符对应的数字,将数字转换为二进制数存放到计算机中
'A' ---> 65 ---> 1000001 大写字母是连续的,ASCII编码值依次+1
'a' ---> 97 ---> 1100001 小写字母是连续的,ASCII编码值依次+1
'0' ---> 48 ---> 110000 数字字符是连续的,ASCII编码值依次+1

使用字符时:将对应的二进制数转换为十进制 找到ASC表中对应的字符
1000001 ---> 65 ---> 'A'
1100001 ---> 97 ---> 'a'
110000 ---> 48 ---> '0'

//字符类型和int类型计算
char c = 'a';
int i = 1;
System.out.println(c+i);//输出结果是98
# char类型的字符先查询编码表,得到97,再和1求和

//关于大小写转换
char c1 = 'a' - 32;
System.out.println("c1 = " + c1); // A
char c2 = 'A' + 32;
System.out.println("c2 = " + c2); // a
// 'a'先查编码表,得到97,再和32计算,赋值给char1
// 常量优化机制:int型也可以赋值给byte,short,char
// 超出数据类型范围时打印结果不对。

image-20200508115505469

ASCII编码:美国用的,但是其他国家的语言多不够用,各国各自为政,(大陆:GB2312,GBK;台湾:BIG5;欧洲:ISO8859–1);后大一统,Unicode,通常两个字节,但是,全英文的不划算,因此,可变长度编码UTF-8,英文一个字节,中文3个,偏僻汉字4-6个字节

int类型和char类型的运算原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Demo09Char {
public static void main(String[] args){
//定义char类型的变量ch,并初始化为'A'
char ch = 'A';
System.out.println(ch);//A
/*
自动类型转换中:
byte/short/char类型,只要参加运算,会自动转换为int类型

ch是char类型,在参加运算时,自动转为int类型
问题:
char类型如何转换为int类型的数字呢?
查看ASCII编码表: 找到'A'对应的数字是65,然后参与运算

*/
System.out.println(ch+1);//66
/*
自动类型转换中:
byte/short/char类型,只要参加运算,会自动转换为int类型

ch是char类型,在参加运算时,自动转为int类型
查看ASCII编码表: 找到'A'对应的数字是65,然后参与运算
所以: ch + 1 的结果是66

然后把int数字66强制转换成char类型的数据
问题:
int类型的数据如何强制转换成char类型数据呢?
查看ASCII编码表: 找到int数字66对应的字符'B'显示出来
*/
System.out.println((char)(ch+1));//B
}
}
1
2
3
4
byte a = 3;
byte b = 4;
byte c = a + b; // 报错=> byte c = (byte)(a+b) // 会自动提升为int计算,所以要强制转换一下。
byte d = 3 + 4; //不会报错 常量优化机制,会先计算,判断在byte范围内

运算符

算术运算符加减乘除

+ - * / % ++(自增) –(自减)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
1.运算符:对常量或者变量进行操作的符号 
2.表达式:用运算符把常量或者变量连接起来符合java语法的式子就可以称为表达式。
3.数学运算符:
(1)+: 加法运算
(2)-: 减法运算
(3)*: 乘法运算
(4)/: 除法运算
/*
算数运算符
1.运算符:对常量或者变量进行操作的符号
2.表达式:用运算符把常量或者变量连接起来符合java语法的式子就可以称为表达式。
3.数学运算符:
(1)+: 加法运算 (String 相加底层会创建StringBuilder)
(2)-: 减法运算
(3)*: 乘法运算
(4)/: 除法运算
被除数 ÷ 除数 = 商(/: 取的就是商) ...... 余数
*/
public class Demo10Operator {
public static void main(String[] args){
int a = 3;
int b = 2;
System.out.println(a + b);//3 + 2: 5
System.out.println(a - b);//3 - 2: 1
System.out.println(a * b);//3 * 2: 6
//3/2: int/int 结果必然是int类型
System.out.println(a / b);//3 / 2: 1

//int * double / int ==> double / int ==> double / double ==> double
System.out.println((a*1.0) / b);//3.0 / 2 ==> 3.0/2.0 ==> 1.5
}
}

算术运算符%

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*
%运算符: 取余数(模)运算符
被除数 ÷ 除数 = 商(/: 取的就是商) ...... 余数(%: 取的就是余数)

作用:
1.判断数字的奇偶性:
数字%2 结果是0 说明数字是偶数
数字%2 结果不是0 说明数字是奇数

2.判断一个数字是否能够被另外一个数字整除
结果为0: 说明可以整除
结果不为0: 说明不可以整除

3.可以把%和/结合使用计算数字的个位,十位,百位,千位
比如有个int变量num,保存数字1234
int num = 1234;
个位: num%10
十位: num/10%10
百位: num/100%10
千位: num/1000%10
*/
public class Demo11Operator {
public static void main(String[] args){
System.out.println(10%2);//0 说明10是偶数
System.out.println(11%2);//1 说明11是奇数

System.out.println(100%25);//0 说明100可以被25整除
System.out.println(100%26);//22 说明100不可以被26整除

System.out.println("---------------");
int num = 1234;
System.out.println(num%10);//4: 个位 1234 ÷ 10 = 商123 .... 余数4(%)
//System.out.println(num/10);//123 1234 ÷ 10 = 商123(/) .... 余数4(%)
System.out.println(num/10%10);//3 十位 123 ÷ 10 = 商12(/) ... 余数3(%)

//System.out.println(num/100);//12 1234 ÷ 100 = 商12(/) ... 余数34(%)

System.out.println(num/100%10);//2 百位 12 ÷ 10 = 商1(/) ... 余数2(%)

System.out.println(num/1000%10);//1 千位

// 负数的取模运算结果是不是负数看左边
System.out.println(5 % -2); // 1
System.out.println(-2 % 5); // -2
}
}

image-20200421144143935

算术运算符+的特殊用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*
+符号的作用
1.数学中的加法运算(数字相加,字符相加)
2.字符串的拼接(把两个字符串连在一起)
*/
public class Demo12Operator {
public static void main(String[] args){
System.out.println(5+5);//10
/*
int + char ==> int + int ==> int
需要:
char ==> int 查看ASCII码表 'A'对应65
*/
System.out.println(5+'A');//5 + 65: 70
/*
自动类型转换中:
byte/short/char类型,只要参加运算,会自动转换为int类型
char + char ==> int + int ==> int
需要:
char ==> int 查看ASCII码表 'A'对应65
char ==> int 查看ASCII码表 'B'对应66
*/
System.out.println('A'+'B');//65 + 66: 131

System.out.println("Hello"+"World");
//"5+5="+5+5: 从左向右计算
//先计算"5+5="+5: 此处+号代表字符串的连接 结果是"5+5=5"
//然后"5+5=5"+5: 此处+号代表字符串的连接 结果是"5+5=55"
System.out.println("5+5="+5+5);//5+5=55

//()的优先级是比较高的,所以先计算5+5 结果10
//然后"5+5="+10: 此处+号代表字符串的连接 结果是"5+5=10"
System.out.println("5+5="+(5+5));//5+5=10
}
}

赋值运算符

= += -= *= /= %= 自动类型强转功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
基本赋值运算符: =
复合赋值运算符:
+= a+=b a=a+b
-= a-=b a=a-b
*= a*=b a=a*b
/= a/=b a=a/b
%= a%=b a=a%b
*/
public class Demo13Operator {
public static void main(String[] args){
int a = 10,b = 20;
a += b;//a = a + b
System.out.println(a);//30
System.out.println(b);//20

int c = 30,d = 20;
c %= d;//c = c % d = 30%20 = 10

System.out.println(c);//10
System.out.println(d);//20

// 赋值运算符与变量类型转换(自动强转)
byte b1=1;
//b1= b1+ 256;//编译报错
b1+=256;
System.out.println(b1);//值为1,而不是257.int 强转为 byte ,溢出
int i1=10;
i1*=1.234;
System.out.println(i1);//值为12,而不是12.34,double强转为int精度损失
}
}

赋值运算符的特点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/*
赋值运算符特点
1.+=,-=,/=,*=,%= 运算结果的数据类型和左侧变量的数据类型不一致,隐藏强制类型转换
2.整数常量只要不超出所赋值的整数变量的取值范围,可以直接赋值,内部隐藏强制类型转换
*/
public class Demo14Operator {
public static void main(String[] args){
short s = 1;
/*
s是short类型,1是int类型,运算时类型不一致,会发生自动类型转换
short类型(2个字节)的s会自动转换成int类型(4个字节):在short类型的s左侧补充2个字节的0

最终变成了两个int数据相加,结果是int类型(占用4个字节),不能直接赋值给左侧的short类型的变量s,占用2个字节

大萝卜不能直接放入小坑中
*/
//s = s + 1;
//System.out.println(s);


/*
s是short类型,1是int类型,运算时类型不一致,会发生自动类型转换
short类型(2个字节)的s会自动转换成int类型(4个字节):在short类型的s左侧补充2个字节的0

最终变成了两个int数据相加,结果是int类型(占用4个字节),不能直接赋值给左侧的short类型的变量s,占用2个字节

但是在赋值之前把int类型的结果,强制转换成short类型(砍掉左侧的2个字节的内容),
由于砍掉的2个字节都是0,所以最终的结果没有影响,仍然是2

把萝卜变小
*/
s = (short)(s + 1);
System.out.println(s);

short s2 = 1;
/*
+=,-=,/=,*=,%= 运算结果的数据类型和左侧变量的数据类型不一致,隐藏强制类型转换
*/
s2 += 1;//s2 = (short)(s2 + 1);

System.out.println(s2);
/*
右侧10是int类型(4个字节),左侧变量byte类型(1个字节)
按照道理来讲: 大萝卜是不可以直接放入小坑中的
现在为什么可以呢?
原因是数字10是一个常量,值并没有超出byte的取值范围
所以可以直接赋值,内部会帮助我们进行强制类型转换
等价于:
byte b = (byte)10;
*/
byte b = /*(byte)*/10;
System.out.println(b);//10
}
}

自增自减运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
自增(++)自减(--)运算符(代码演示只演示++)
1.作用: 让变量的值增加1(++)或者减少1(--)
2.使用格式:
(1)可以写在变量的前面: ++a,--a
(2)可以写在变量的后面: a++,a--

3.使用特点:
(1)单独使用: ++/--自己独占一行,没有其它运算一起参与
前++和后++,没有任何区别,都是让变量的值增加1
前--和后--,没有任何区别,都是让变量的值减少1

(2)混合使用: 和其它运算(赋值,打印等)一起
前++/--: 先++/--,后再使用 先给变量的值增加(++)或者减少(--)1,然后再使用++/--后的结果
后++/--: 先使用,然后++/-- 先使用变量的值,再把变量的值 增加(++)或者减少(--)1


重点: ----最常用的东西
a++: 变量a的值增加1
a--: 变量a的值减少1
*/
public class Demo15Operator {
public static void main(String[] args){
int a = 2;
//++自己独占一行,没有其它运算一起参与
a++;//a = a + 1 = 2 + 1
System.out.println(a);//3

int b = 2;
//++自己独占一行,没有其它运算一起参与
++b;//b = b + 1 = 2 + 1
System.out.println(b);//3

System.out.println("-----------------");
int c = 2;
/*
目前是++和赋值一起操作,属于混合运算
而且++写在了c的前面,先把c的值增加1,
c的值变为3,然后再把结果3赋值给变量d,d的值3
*/
int d = ++c;

System.out.println(c);//3
System.out.println(d);//3
System.out.println("-----------------");

int e = 2;
/*
目前是++和赋值一起操作,属于混合运算
而且++写在了e的后面,所以先使用e的值(2)赋值给变量f,所以f的值是2,
然后e的值再增加1,变成3
*/
int f = e++;

System.out.println(e);//3
System.out.println(f);//2

System.out.println("-----------------");

int x = 4; //5 6
/*
表达式(x++)+(++x)+(x*10)是从左到右计算的
先计算(x++): 因为++在后面,先使用x的值4,然后x的值增加,变成5
4 + (++x)+(x*10)
接着计算(++x): 因为++在前面,先把x的值增加1,x变成6,然后再使用6
4 + 6+(x*10)
接着计算x*10 --> 6*10 结果: 60
4 + 6 + 10 结果: 70
*/
int y = (x++)+(++x)+(x*10);
// 4 + 6 +
System.out.println(x);//6
System.out.println(y);//70

}
}

关系运算符

== != < > <= >= 结果为布尔值true/false

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1.作用:
用来比较数据之间的大小关系

2.特点:
不管关系表达式多么复杂或者多么简单,返回值一定是布尔类型的结果,要么是true,要么是false
布尔值也可以比较,System.out.println(true == false); // false

3.分类:
== 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

4.注意:
(1)=: 一个等号是赋值的意思
(2)==: 两个等号是判断是否相同的意思
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Demo01GuanXi {
public static void main(String[] args) {
int a = 10, b = 20;
boolean result = (a == b);
System.out.println(result);//false
System.out.println(a != b);//10 != 20: true
System.out.println(a > b);//10 > 20: false
System.out.println(a >= b);//10 >= 20: false
System.out.println(a < b);//10 < 20: true
System.out.println(a <= b);//10 <= 20: true
System.out.println(a == b);//10 == 20: false
System.out.println(a = b);//20 把变量b的值赋值给变量a,最后打印变量a的值
}
}

逻辑运算符

& &&(短路与) | ||(短路或) ^ !

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
举例: 寒窗苦读,顺利毕业,高薪就业,找到了对象,谈了好长时间,需要谈婚论嫁
到你对象家和准岳母谈判:
准岳母:
小伙子呀,你必须得有房子(条件1: true/false),然后呢,你必须还得有车子(条件2: true/false)
以上的要求: 两个条件都得满足(true),这个事才能确定下来 使用逻辑运算符 &

小伙子呀,你要么有房子(条件1: true/false),你呀要么有车子(条件2: true/false)
以上的要求: 两个条件只要有一个满足(true),这个事就能确定下来 使用逻辑运算符 |


1.作用:
用来连接多个条件(布尔表达式的: 结果为true/false的式子),最终的结果也必须是一个布尔类型的数据,要么是true,
要么是false
不管逻辑运算符连接的式子有多么简单或者多么复杂,最终结果要么是true,要么是false
2.分类:
(1)&(shift+7): 逻辑与,表示并且的意思,多个条件同时成立的意思,就是只有多个条件都是true,最终的结果才是true
特点:
【有false,则false】: 只要有一个条件不成立(false),结果就是false
(2)|(shift+\): 逻辑或,表示或者的意思,多个条件,只要有一个成立,最终的结果就是true
特点:
【有true,则true】:只要有一个条件是true,结果就是true
(3)^(shift+6): 逻辑异或,相同为false,不同为true ----基本不用
(4)!(shift+1): 逻辑取反,!true 就是false,!false 就是true

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Demo02LuoJi {
public static void main(String[] args) {
int a = 10,b = 20,c = 30;
System.out.println(a>b & a>c);//10 > 20 & 10 > 30 ==> false & false ==> false
System.out.println(a<b & a<c);//10 < 20 & 10 < 30 ==> true & true ==> true
System.out.println(a>b & a<c);//10 > 20 & 10 < 30 ==> false & true ==> false
System.out.println(a<b & a>c);//10 < 20 & 10 > 30 ==> true & false ==> false

System.out.println("--------------------");

System.out.println(a>b | a>c);//10 > 20 | 10 > 30 ==> false | false ==> false
System.out.println(a<b | a<c);//10 < 20 | 10 < 30 ==> true | true ==> true
System.out.println(a>b | a<c);//10 > 20 | 10 < 30 ==> false | true ==> true
System.out.println(a<b | a>c);//10 < 20 | 10 > 30 ==> true | false ==> true

System.out.println("--------------------");
System.out.println(a>b ^ a>c);//10 > 20 ^ 10 > 30 ==> false ^ false ==> false
System.out.println(a<b ^ a<c);//10 < 20 ^ 10 < 30 ==> true ^ true ==> false
System.out.println(a>b ^ a<c);//10 > 20 ^ 10 < 30 ==> false ^ true ==> true
System.out.println(a<b ^ a>c);//10 < 20 ^ 10 > 30 ==> true ^ false ==> true

System.out.println("--------------------");
System.out.println(!true);//false
System.out.println(!false);//true
}
}

逻辑运算符的短路效果

1
2
3
4
5
6
7
8
9
10
11
逻辑运算符的短路效果
1.短路的逻辑运算符
(1)短路逻辑与&&: 左侧为false,右边不计算
(2)短路逻辑或||: 左侧为true,右侧不计算
2.特点:
(1)短路逻辑与&&: 和&结果是相同的,但是&&可以提高效率
(2)短路逻辑与||: 和|结果是相同的,但是||可以提高效率

3.建议:
短路表示一个逻辑表达式的所有部分不必都执行下去,提升的性能很可观
以后开发学习中,全部使用短路与&& 以及 短路或||
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class Demo03DuanLu {
public static void main(String[] args) {
int a = 2;
/*
整个表达式(3>5)&&(++a>2)从左向右计算
先计算表达式3>5结果为false
因为两个表达式使用&&连接,左侧为false,已经决定了最终的结果为false,
不管右侧表达式(++a>2)的结果是true还是false,都无法改变&&的最终结果,
所以右侧表达式(++a>2)不进行计算
*/
System.out.println((3>5)&&(++a>2));//false
System.out.println(a);//2: 说明++a没有计算,&&右侧的表达式没有执行

int b = 2;
/*
整个表达式(3>5)&(++b>2)从左向右计算
先计算表达式3>5结果为false
因为两个表达式使用&连接,左侧为false,虽然已经决定了最终的结果为false,
但是右侧表达式(++b>2)仍然要进行计算,所以b的值最终是3
*/
System.out.println((3>5)&(++b>2));//false
System.out.println(b);//3: 说明++b进行计算,&右侧的表达式执行了

System.out.println("-------------------");
int c = 2;
/*
整个表达式(3<5)||(++c>2)从左向右计算
先计算表达式3<5结果为true
因为两个表达式使用||连接,左侧为true,已经决定了最终的结果为true,
不管右侧表达式(++c>2)的结果是true还是false,都无法改变||的最终结果,
所以右侧表达式(++c>2)不进行计算
*/
System.out.println((3<5)||(++c>2));//true
System.out.println(c);//2: 说明++c没有计算,||右侧的表达式没有执行

int d = 2;
/*
整个表达式(3<5)|(++d>2)从左向右计算
先计算表达式3<5结果为true
因为两个表达式使用|连接,左侧为true,虽然已经决定了最终的结果为true,
但是右侧表达式(++d>2)仍然要进行计算,所以d的值最终是3
*/
System.out.println((3<5)|(++d>2));//true
System.out.println(d);//3: 说明++d进行计算,|右侧的表达式执行了
}
}

三元运算符格式

1
2
3
4
5
6
7
8
9
10
11
12
13
1.格式:
数据类型 变量名称 = 布尔表达式1 ? 表达式2 : 表达式3;

2.执行流程:
(1)计算布尔表达式1的结果,看是true还是false
(2)如果布尔表达式1的结果为true,就把表达式2的结果赋值给左侧的变量
(3)如果布尔表达式1的结果为false,就把表达式3的结果赋值给左侧的变量

3.建议:
高效简洁编程,但是要考虑可读性。
数据类型 变量名 = 布尔类型表达式 ? 真值 : 假值;
真值假值的数据类型要和变量接收的数据类型匹配(一致或满足自动转换)
编译的时候就要类型统一

执行流程图解:

image-20200423115658540

三元运算符的练习之两只老虎(相等)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
需求:
动物园里有两只老虎,已知两只老虎的体重分别为180kg、200kg,
请用程序实现判断两只老虎的体重是否相同。

实现步骤:
1.定义两个int变量w1和w2,分别代表两只老虎的体重,并按照题目要求进行初始化
2.使用三元运算符判断w1和w2的值是否相同,保存到boolean变量result中
3.打印result的值

public class Demo01SanYuan {
public static void main(String[] args) {
//1.定义两个int变量w1和w2,分别代表两只老虎的体重,并按照题目要求进行初始化
int w1 = 180, w2 = 200;

//2.使用三元运算符判断w1和w2的值是否相同,保存到boolean变量result中

boolean result = (w1 == w2) ? true : false;

//3.打印result的值
System.out.println("两只老虎的体重相同吗? "+result);

System.out.println("---------------");

String s = (w1 == w2) ? "相同" : "不相同";

System.out.println("两只老虎的体重相同吗? "+s);
}
}

三元运算符的练习之两只老虎(最大值)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
需求:
动物园里有两只老虎,已知两只老虎的体重分别为180kg、200kg,
请用程序实现计算两只老虎的体重的最大值。

实现步骤:
1.定义两个int变量w1和w2,分别代表两只老虎的体重,并按照题目要求进行初始化
2.使用三元运算符,计算w1和w2的最大值,把结果保存到int变量max中
3.打印max的值
public class Demo02SanYuanMax {
public static void main(String[] args) {
//1.定义两个int变量w1和w2,分别代表两只老虎的体重,并按照题目要求进行初始化
int w1 = 180, w2 = 200;

//2.使用三元运算符,计算w1和w2的最大值,把结果保存到int变量max中

int max = (w2 > w1) ? w2 : w1;

//3.打印max的值
System.out.println("两只老虎体重的最大值: "+max);
}
}

图解分析

image-20220728091011215

三元运算符的练习之三个和尚

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
需求:
一座寺庙里住着三个和尚,已知他们的身高分别为150cm、210cm、165cm,
请用程序实现获取这三个和尚的最高身高。

实现步骤:
1.定义3int变量h1,h2,h3代表三个和尚的身高,并根据题目需求进行初始化
2.使用三元运算符计算出h1和h2的最大值,保存到int变量temp中
3.使用三元运算符计算出temp和h3的最大值,保存到int变量max中
4.最终打印max的值

public class Demo03SanYuanMax {
public static void main(String[] args) {
//1.定义3个int变量h1,h2,h3代表三个和尚的身高,并根据题目需求进行初始化
int h1 = 150, h2 = 210, h3 = 165;

//2.使用三元运算符计算出h1和h2的最大值,保存到int变量temp中
int temp = (h1 > h2) ? h1 : h2;

//3.使用三元运算符计算出temp和h3的最大值,保存到int变量max中
int max = (temp > h3) ? temp : h3;

//4.最终打印max的值
System.out.println("三个和尚的最大身高: "+max);//210
}
}

图解分析

image-20220727013542102

位运算符

<<(左移) >>(右移) >>>(无符号右移) &(与) |(或) ^(异或) ~(按位取反)

1
2
3
4
5
a^a^a = a  // 异或两次,本身不变。

6<<1 // 12 ≈ 6*2^1
6>>1 // 3 偶数:≈ 6/2
7>>1 // 3 奇数:≈ (7-1)/2

流程控制

流程控制分类

就像任何有感知的生物一样,程序必须能操纵自己的世界,在执行过程之中做出选择和判断.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
流程:简单来讲所谓流程就是完成一件事情的多个步骤组合起来就叫做一个流程
注意: 在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的。
举例:
结果:正在学习Java编程语言
流程:学习编程想法 --> 咨询老师 --> 安排课程 --> 听Java课程

流程控制语句分类
1.顺序结构: 按照代码的书写顺序,从上而下依次执行
2.选择/分支结构
(1)if语句【重点】
(2)switch语句
3.循环结构
(1)for循环【重点】
(2)while循环
(3)do-while循环

顺序结构

1
2
3
4
5
6
7
8
9
10
public class Demo01Sequence {
public static void main(String[] args) {
//1.顺序结构: 按照代码的书写顺序,从上而下依次执行
System.out.println("开始.....");
System.out.println("今天天气不错,我们上午直播java课....A");
System.out.println("下午还有答疑老师辅导课....B");
System.out.println("这的确挺爽的....C");
System.out.println("结束....");
}
}

选择结构-if

if

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
英文单词if是: 如果的意思
1.if语句的第一种格式:
if(布尔表达式){
语句体;
}
其它语句;

2.执行流程:
(1)使用计算if后面()中布尔表达式的结果,看是true,还是false
(2)如果if后面()中布尔表达式的结果是true,执行if后面{}中的语句体,接着执行其它语句
(3)如果if后面()中布尔表达式的结果是false,跳过if后面{}中的语句体,直接执行其它语句

3.注意:
(1)if语句的第一种格式,适用于有一种情况的场景
(2)if后面()中表达式不管写的多么简单或者多么复杂,最终的结果一定是布尔类型,要么是true,要么是false
(3)if后面{}中的语句体,要么执行(布尔表达式结果为true)要么不执行(布尔表达式结果为false)
(4)if后面{}中的语句体: 一条或者多条语句(每条语句末尾处使用分号结尾)
(5)if后面{}中的语句体的语句体只有一条语句,此时{}可以省略,但是初学者讲义保留

图解:

image-20220727013708596

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
练习
需求1:判断a和b的值是否相等,如果相等,就在控制台输出:a等于b
需求2:判断a和c的值是否相等,如果相等,就在控制台输出:a等于c
public class Demo02If {
public static void main(String[] args) {
//需求1:判断a和b的值是否相等,如果相等,就在控制台输出:a等于b
int a = 10, b = 20;
if (a == b) {//10 == 20: false,不执行{}中的语句体
System.out.println(a + "等于" + b);
}

if (a != b) {//10 != 20: true,执行{}中的语句体
System.out.println(a + "不等于" + b);
}

//需求2:判断a和c的值是否相等,如果相等,就在控制台输出:a等于c
int c = 30;
if (a == c) {//10 == 30: false,不执行{}中的语句体
System.out.println(a + "等于" + c);
}

if(a != c) {//10 != 30: true,执行{}中的语句体
System.out.println(a + "不等于" + c);
}
System.out.println("main....end....");//模拟格式中的其它语句
}
}

if else

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
英文单词if是: 如果的意思
英文单词else是: 否则的意思
1.if语句的第二种格式:
if(布尔表达式){
语句体1;
} else {
语句体2;
}
其它语句;

2.执行流程:
(1)使用计算if后面()中布尔表达式的结果,看是true,还是false
(2)如果if后面()中布尔表达式的结果是true,执行if后面{}中的语句体1,接着执行其它语句
(3)如果if后面()中布尔表达式的结果是false,执行else后面{}中的语句体2,接着执行其它语句

3.注意:
(1)if语句的第二种格式,适用于有两种情况的场景
(2)if后面()中表达式不管写的多么简单或者多么复杂,最终的结果一定是布尔类型,要么是true,要么是false
(3)语句体1和语句体2,只有一个会被执行
(4)适用于二选一的场景(是与否的场景)

一个else分支的情况下和一个if没有区别,但是代码可读性上更加清晰

图解:

image-20220727013756992

练习-判断大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
需求:
判断a是否大于b,如果是,在控制台输出:a的值大于b,否则,在控制台输出:a的值不大于b

实现步骤:
1.定义2int变量a和b,并分别初始化
2.a和b的大小关系有两种情况,所以使用if-else语句对a和b的值进行判断,并输出不同的结果

public class Demo03IfElse {
public static void main(String[] args) {
//1.定义2个int变量a和b,并分别初始化
int a = 10, b = 20;

//2.a和b的大小关系有两种情况,所以使用if-else语句对a和b的值进行判断,并输出不同的结果
if (a > b) {//10 > 20: false,执行else后面{}中的语句体
System.out.println(a + "的值大于" + b);
} else {
System.out.println(a + "的值不大于" + b);
}
System.out.println("main....end....");//模拟格式中的其它语句

//闰年
//闰年的判断规则如下:
//1)若某个年份能被4整除但不能被100整除,则是闰年。
//2)若某个年份能被400整除,则也是闰年。
if(year%4==0||year%100!=0&&year%400==0){
// ...
}
}
}

i练习-判断奇偶数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
需求:
任意给出一个整数,请用程序实现判断该整数是奇数还是偶数,并在控制台输出该整数是奇数还是偶数。

实现步骤:
1.创建键盘录入Scanner类的对象
(1.导包: import java.util.Scanner; 2.创建对象: Scanner sc = new Scanner(System.in);)
2.获取键盘录入的整数数字,保存到int变量num中
3.使用if语句的第二种格式(if-else),判断num中的数字,输出对应的奇偶数情况
num%2==0: 说明num中的数字是偶数
num%2!=0: 说明num中的数字是奇数

public class Demo04IfElseJiOu {
public static void main(String[] args) {
//1.创建键盘录入Scanner类的对象
//(1.导包: import java.util.Scanner; 2.创建对象: Scanner sc = new Scanner(System.in);)
Scanner sc = new Scanner(System.in);

//2.获取键盘录入的整数数字,保存到int变量num中
System.out.println("请输入一个整数数字: ");
int num = sc.nextInt();
//System.out.println("您输入的整数是: "+num);

//3.使用if语句的第二种格式(if-else),判断num中的数字,输出对应的奇偶数情况
/*if(num%2==0){
System.out.println(num+"是一个偶数数字");
} else {
System.out.println(num+"是一个奇数数字");
}*/

if(num%2!=0){
System.out.println(num+"是一个奇数数字");
} else {
System.out.println(num+"是一个偶数数字");
}


System.out.println("main....end....");//模拟格式中的其它语句

}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
需求:
任意给出两个整数,请用程序实现求出两个整数的最大值,并输出到控制台。

实现步骤:
1.创建键盘录入Scanner类的对象
2.获取两个键盘录入的整数数字,分别保存到2int变量a和b中
3.定义int变量max,作用是用来保存两个int数字的最大值
4.使用if-else对a和b中的值进行大小判断
4.1如果: a>b 是成立的,说明a是最大的,把a的值赋值给变量max
4.2否则: a>b 是不成立的,说明b是最大的,把b的值赋值给变量max
5.打印max的值

import java.util.Scanner;
public class Demo05IfElseMax {
public static void main(String[] args) {

//1.创建键盘录入Scanner类的对象
Scanner sc = new Scanner(System.in);

//2.获取两个键盘录入的整数数字,分别保存到2个int变量a和b中
System.out.println("请输入第一个整数数字: ");
int a = sc.nextInt();

System.out.println("请输入第二个整数数字: ");
int b = sc.nextInt();

//3.定义int变量max,作用是用来保存两个int数字的最大值
int max;

//4.使用if-else对a和b中的值进行大小判断
if(a>b) {//10 > 20 ==> false
//4.1如果: a>b 是成立的,说明a是最大的,把a的值赋值给变量max
max = a;
} else {
//4.2否则: a>b 是不成立的,说明b是最大的,把b的值赋值给变量max
max = b;
}
//5.打印max的值
//System.out.println("数字 "+a+"和"+b+"的最大值是: "+max);
System.out.println("最大值: "+max);

System.out.println("main....end....");//模拟格式中的其它语句
}
}

图解分析:

image-20200424103803810

if else if else

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
英文单词if是: 如果的意思
英文单词else是: 否则的意思
1.if语句的第三种格式:
if (布尔表达式1) {
语句体1;
} else if (布尔表达式2) {
语句体2;
}
else if (布尔表达式n) {
语句体n;
} else {
语句体n+1;
}
其它语句;

2.执行流程:
(1)首先计算布尔表达式1的值
(2)如果值为true就执行语句体1;如果值为false就计算布尔表达式2的值
(3)如果值为true就执行语句体2;如果值为false就计算布尔表达式3的值
(4)…
(5)如果没有任何布尔表达式为true,就执行语句体n+1

3.注意:
(1)if语句的第三种格式,适用于有多种情况(大于等于3)的场景
(2)if后面()中表达式不管写的多么简单或者多么复杂,最终的结果一定是布尔类型,要么是true,要么是false
(3)语句体1到语句体n+1,只有一个会被执行
(4)适用于多选一的场景
(5)有if就可以在后面写条件,没有if,不能写条件,不能直接在else后面写条件
(6)最后一个else后面没有if,是用来兜底的,如果上面所有if后的条件都不成立,直接执行最后一个else中的代码

图解:

image-20220727013819083

练习-根据数字输出对应的星期

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
需求:
键盘录入一个星期数(1,2,...7),输出对应的星期一,星期二,...星期日
演示效果:
输入 1 输出 星期一
输入 2 输出 星期二
输入 3 输出 星期三
输入 4 输出 星期四
输入 5 输出 星期五
输入 6 输出 星期六
输入 7 输出 星期日
输入 其它数字 输出 数字有误

实现步骤:
1.创建键盘录入Scanner类的对象
2.获取键盘录入的整数数字,代表星期数,保存到int变量week中
3.因为week中的数字有7+1种情况,所以使用if语句的第三种格式进行判断,并输出不同的结果内容

import java.util.Scanner;
public class Demo01IfElseIfElseWeek {
public static void main(String[] args) {
//1.创建键盘录入Scanner类的对象
Scanner sc = new Scanner(System.in);

//2.获取键盘录入的整数数字,代表星期数,保存到int变量week中
System.out.println("请输入一个1-7的整数数字(代表星期数):");
int week = sc.nextInt();

//3.因为week中的数字有7+1种情况,所以使用if语句的第三种格式进行判断,并输出不同的结果内容
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 if(week == 7) {
System.out.println("星期日");
} else {//隐藏条件: week>7 || week<1
System.out.println("您输入的星期数不存在,是火星来的吧,哥屋恩...");
}

System.out.println("main....end....");//模拟格式中的其它语句
}
}

import java.util.Scanner;
public class Demo02IfElseIfElseWeek {
public static void main(String[] args) {
//1.创建键盘录入Scanner类的对象
Scanner sc = new Scanner(System.in);

//2.获取键盘录入的整数数字,代表星期数,保存到int变量week中
System.out.println("请输入一个1-7的整数数字(代表星期数):");
int week = sc.nextInt();

//3.因为week中的数字有7+1种情况,所以使用if语句的第三种格式进行判断,并输出不同的结果内容
if(week>7 || week<1) {
System.out.println("您输入的星期数不存在,是火星来的吧,哥屋恩...");
} else if(week == 1) { //从这里开始向下,隐藏条件: week>=1 && week<=7
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 /*if(week == 7)*/ {//隐藏条件: week == 7
System.out.println("星期日");
}

System.out.println("main....end....");//模拟格式中的其它语句
}
}

练习-根据成绩进行奖励

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
需求:
小明快要期末考试了,小明爸爸对他说,会根据他不同的考试成绩,送他不同的礼物,
假如你可以控制小明的得分,请用程序实现小明到底该获得什么样的礼物,并在控制台输出。

奖励规则:
95~100 山地自行车一辆 包含95100的 数学中表示方式: [95,100] 不包含95100: (95,100)
90~94 游乐场玩一次 包含9094
80~89 变形金刚玩具一个 包含8089
80以下 胖揍一顿 不包含80分的

实现步骤:
1.创建键盘录入Scanner类的对象
2.获取一个0-100之间的整数数字(代表小明的考试成绩),保存到int变量score中
3.因为score中的数字有多种(大于3)情况,所以使用if语句的第三种格式进行判断,并输出不同的结果内容
import java.util.Scanner;
public class Demo03IfElseIfElseScore {
public static void main(String[] args) {
//1.创建键盘录入Scanner类的对象
Scanner sc = new Scanner(System.in);

//2.获取一个0-100之间的整数数字(代表小明的考试成绩),保存到int变量score中
System.out.println("请输入一个0-100之间的整数数字(代表小明的考试成绩): ");
int score = sc.nextInt();

//3.因为score中的数字有多种(大于3)情况,所以使用if语句的第三种格式进行判断,并输出不同的结果内容
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 if(score>=0 && score<80){
System.out.println("奖励胖揍一顿");
} else /*if(score<0 || score>100)*/{//隐藏条件: score<0 || score>100
System.out.println("您输入的成绩错误,是火星来的吧,哥屋恩...");
}

System.out.println("main....end....");//模拟格式中的其它语句
}
}

import java.util.Scanner;
public class Demo04IfElseIfElseScore {
public static void main(String[] args) {
//1.创建键盘录入Scanner类的对象
Scanner sc = new Scanner(System.in);

//2.获取一个0-100之间的整数数字(代表小明的考试成绩),保存到int变量score中
System.out.println("请输入一个0-100之间的整数数字(代表小明的考试成绩): ");
int score = sc.nextInt();

//3.因为score中的数字有多种(大于3)情况,所以使用if语句的第三种格式进行判断,并输出不同的结果内容
//先排除非法数据
if(score<0 || score>100) {
System.out.println("您输入的成绩错误,是火星来的吧,哥屋恩...");
} else if(score>=95 && score<=100) {//执行到这里及以下: score>=0 && score<=100
System.out.println("奖励山地自行车一辆");
} else if(score>=90 && score<=94) {
System.out.println("奖励游乐场玩一次");
} else if(score>=80 && score<=89) {
System.out.println("奖励变形金刚玩具一个");
} else /*if(score>=0 && score<80)*/{//隐藏条件: score>=0 && score<80)
System.out.println("奖励胖揍一顿");
}

System.out.println("main....end....");//模拟格式中的其它语句
}
}

图解:

image-20200424121125368

注意点:

  • 1.满足条件进行某种处理,if;if…else;if…else if;if…else if…else;
  • 2.if为输出语句的时候就不能转为三元运算符实现。
  • 3.实际开发中if else嵌套如果超过3层,停下来,思考一下有没有更好的方式
  • 4.return可以结束if else的分支判断,并且,if else判断语句外面之后的代码都不执行。

Image

选择结构-switch

switch语句格式和介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
1.switch语句的格式:
switch(表达式) {
case 常量值1;
语句体1;
break;
case 常量值2;
语句体2;
break;
...
case 常量值n;
语句体n;
break;
default:
语句体n+1;
break;
}
其它语句;

2.执行流程:
首先计算出表达式的值
其次,和case依次比较,一旦有对应的值,就会执行相应的语句,在执行的过程中,遇到break就会结束。
最后,如果所有的case都和表达式的值不匹配,就会执行default语句体部分,然后程序结束掉。

3.注意事项:
(1)break的作用是用来结束switch语句的,一旦执行break,直接跳出到switch外面的其它语句继续执行
(2)switch后面()中的表达式的数据类型,只能是以下几种类型:
基本类型: byte/short/char/int 都可以 -----------------重要,选择题经常考到---------------
引用类型: String(JDK7)或者枚举(JDK5)
(3)case 后面只能写常量,而且常量值不能重复,(条件表达式两边必须都为布尔值,int没法和布尔值比较)
(4)最后一个default的作用:
用来兜底的,如果所有的case后面的常量值和switch中表达式的值都不相同,就执行default中的内容
(5)如果default放在最后的话: 后面的break可以省略
(6)如果所有的casedefault后面都有break,那么defaultcase的顺序可以任意排列,不影响最终的结果
public class Demo01Switch {
public static void main(String[] args) {
int choose = 2;
switch (choose) {//30
case 1:
System.out.println("你好~~~~~");
break;
case 2:
System.out.println("我好~~~~~");
break;
case 3:
System.out.println("大家好,才是真的好~~~~~");
break;
default:
System.out.println("他好,我也好~~~~");
break;
}
System.out.println("main....end....");//模拟格式中的其它语句
}
}


执行流程

image-20220728091135297

switch练习根据月份输出对应的季节

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
需求:
一年有12个月,分属于春夏秋冬4个季节,
键盘录入一个月份,请用程序实现判断该月份属于哪个季节,并输出。

演示效果
输入: 1212 输出:冬季
输入: 345 输出:春季
输入: 678 输出:夏季
输入: 91011 输出:秋季
输入: 其它数字 输出:数字有误

实现步骤(本案例使用switch):
1.创建键盘录入Scanner类的对象
2.获取键盘录入的一个1-12的整数数字(代表月份),保存到int变量month中
3.因为month中的数字有12+1中情况,使用switch语句对month中的值,进行判断,并输出不同的结果
public class Demo02SwitchMonth {
public static void main(String[] args) {
//1.创建键盘录入Scanner类的对象
Scanner sc = new Scanner(System.in);

//2.获取键盘录入的一个1-12的整数数字(代表月份),保存到int变量month中
System.out.println("请输入一个1-12的整数数字(代表月份): ");
int month = sc.nextInt();

//3.因为month中的数字有12+1中情况,使用switch语句对month中的值,进行判断,并输出不同的结果
switch (month) {//15
case 1:
System.out.println("冬季");
break;
case 2:
System.out.println("冬季");
break;
case 12:
System.out.println("冬季");
break;
case 3:
System.out.println("春季");
break;
case 4:
System.out.println("春季");
break;
case 5:
System.out.println("春季");
break;
case 6:
System.out.println("夏季");
break;
case 7:
System.out.println("夏季");
break;
case 8:
System.out.println("夏季");
break;
case 9:
System.out.println("秋季");
break;
case 10:
System.out.println("秋季");
break;
case 11:
System.out.println("秋季");
break;
default:
System.out.println("您输入的月份不存在,哪个星球来的,哥屋恩...");
break;
}
System.out.println("main....end....");//模拟格式中的其它语句
}
}

使用case穿透优化根据月份输出对应的季节的案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
使用case穿透优化根据月份输出对应的季节的案例
发现问题:
前面Demo02SwitchMonth.java文件中出现了大量的重复的代码
1,2,12代码重复,3,4,5代码重复,6,7,8代码重复,9,10,11代码重复
每三个case中的代码都是相同的

解决方案使用case穿透:
如果多个连续的case中具有相同的代码和break,可以只保留最后一个case中的代码和break,
前面的多个case中省略掉代码和break(只保留case)

switch语句中,如果case的后面不写break,将出现穿透现象,
也就是不会在判断下一个case的值,直接向后运行,直到遇到break,或者整体switch结束。

执行步骤:
1.先找到case入口: 先找到常量值和switch表达式值相同的case
2.执行找到的case入口中的代码:
如果没有break,直接执行(不再判断下一个case中的常量值是否和switch表达式的值是否相同)下一个case中的代码,
直到遇到break,结束switch语句
public class Demo03SwitchMonth {
public static void main(String[] args) {
//1.创建键盘录入Scanner类的对象
Scanner sc = new Scanner(System.in);

//2.获取键盘录入的一个1-12的整数数字(代表月份),保存到int变量month中
System.out.println("请输入一个1-12的整数数字(代表月份): ");
int month = sc.nextInt();

//3.因为month中的数字有12+1中情况,使用switch语句对month中的值,进行判断,并输出不同的结果
switch (month) {//9
case 1:
case 2:
case 12:
System.out.println("冬季");
break;
case 3:
case 4:
case 5:
System.out.println("春季");
break;
case 6:
case 7:
case 8:
System.out.println("夏季");
break;
case 9:
case 10:
case 11:
System.out.println("秋季");
break;
default:
System.out.println("您输入的月份不存在,哪个星球来的,哥屋恩...");
break;
}
System.out.println("main....end....");//模拟格式中的其它语句
}
}

注意点:

  • 0.表达式为byte,short,char,int,enum(jdk1.5+),String(jdk1.7+)
  • 1.break:中断,结束。省略则出现case穿透(根据需求灵活运用)
  • 2.case子句的值必须是常量

选择语句if和switch区别:

  • 1.switch建议判断固定值时用

如果判断的具体数值不多,而且符合byte、short 、char、int、String、枚举等几种类型。虽然两个语句都可以使用,建议使用swtich语句。因为效率稍高。

  • 2.if建议判断区间或范围时用
  • 3.使用switch-case的,都可以改写为if-else。反之不成立,布尔型,浮点型switch都用不了的,if范围比较大。

循环结构

循环概述

1
2
3
4
5
圆周率: 无限不循环小数 3.1415926...
10除以3的结果: 3.33333... 无限循环小数

循环的概念: 重复性的执行某些固定的功能,当条件不成立时,结束循环
说白了: 条件成立执行操作,条件不成立停止操作

循环组成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1.循环的组成(手写100遍HelloWorld案例): :
(1)【初始化表达式1】准备工作:笔墨伺候,最优先唯一执行一次的操作
(2)【循环条件2】条件判断:每次书写前,判断一下,要不要写
(3)【循环体3】循环所要进行的操作:手写一个HelloWorld案例
(4)【步进表达式4】扫尾的工作:每写一次HelloWorld,计数(+1)

2.执行流程:
1,2(循环条件: true),3,4 --> 2(循环条件: true),3,4 --> ... -->
直到布尔表达式2(循环条件: false),结束循环,执行循环后面的其它语句

3.循环的分类:
(1)for循环【最最常用】
(2)while循环【一般常用】
(3)do-while循环【不常用】

for

保证条件有边界,否则会死循环

for循环语句介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
1.for循环格式:
for(初始化表达式1;布尔表达式2;步进表达式4){
循环体3;
}

2.执行流程:
1,2(循环条件: true),3,4 --> 2(循环条件: true),3,4 --> ... -->
直到布尔表达式2(循环条件: false),结束循环,执行循环后面的其它语句

3.嵌套循环:
1.总共的循环次数=外循环次数*内循环次数
2.内层循环遍历一遍,只相当于外层循环体执行了一次
3.外层循环控制行数,内层循环控制列数

图解分析:

image-20220728091222679

for循环练习1:循环打印

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
需求:
在控制台输出5次HelloWorld
public class Demo01ForHello {
public static void main(String[] args) {
System.out.println("HelloWorld.....1");
System.out.println("HelloWorld.....2");
System.out.println("HelloWorld.....3");
System.out.println("HelloWorld.....4");
System.out.println("HelloWorld.....5");
System.out.println("----------------------");

//使用for循环
//count: 1,2,3,4,5 6<=5 --> false --> 结束for循环
for (int count = 1; count <= 5; count++) {
System.out.println("HelloWorld....."+count);
}
System.out.println("----------------------");

//使用for循环
//times: 0,1,2,3,4 5<5 --> false --> 结束for循环
for (int times = 0; times < 5; times++) {
System.out.println("HelloWorld....."+times);
}
System.out.println("main.......end............");
}
}

for循环练习2:循环打印

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
需求:
在控制台输出1-55-1的数据

public class Demo02ForPrint5 {
public static void main(String[] args) {
//for循环输出1-5
for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
System.out.println("----------");

//for循环输出5-1
for (int j = 5; j >= 1; j--) {
System.out.println(j);
}

System.out.println("main....end....");
}
}

for循环练习3:求和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
需求:
1-5之间的数据和,并把求和结果在控制台输出

实现步骤:
1.定义int变量sum,用来求和,初始值0
2.使用for循环获取1-5的数字
2.1把当前数字累加到求和变量中
3.打印求和变量sum

public class Demo03ForSum5 {
public static void main(String[] args) {

//1.定义int变量sum,用来求和,初始值0
int sum = 0;

/*
第一次: sum = 0 i = 1
i <= 5 --> 1<=5 --> true --> sum = sum + i = 0 + 1 = 1 i = 2

第二次: sum = 1 i = 2
i <= 5 --> 2<=5 --> true --> sum = sum + i = 1 + 2 = 3 i = 3

第三次: sum = 3 i = 3
i <= 5 --> 3<=5 --> true --> sum = sum + i = 3 + 3 = 6 i = 4

第四次: sum = 6 i = 4
i <= 5 --> 4<=5 --> true --> sum = sum + i = 6 + 4 = 10 i = 5

第五次: sum = 10 i = 5
i <= 5 --> 5<=5 --> true --> sum = sum + i = 10 + 5 = 15 i = 6

第六次: sum = 15 i = 6
i <= 5 --> 6<=5 --> false --> 结束for循环,执行for后面的代码
*/

//2.使用for循环获取1-5的数字
for (int i = 1; i <= 5; i++) {
//2.1把当前数字累加到求和变量sum中
sum = sum + i;
}

//3.打印求和变量sum
System.out.println("1-5的数字之和: "+sum);
}
}

图解分析:

image-20200426102848056

for循环练习4:求偶数和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
需求:
1-100之间的偶数和,并把求和结果在控制台输出

实现步骤:
1.定义int变量sum,用来累加求和,初始值0
2.使用for获取1-100之间的数字
2.1判断如果当前数字是偶数,把当前数字累加到求和变量sum中
3.for循环结束,打印求和变量sum的值

public class Demo04ForSum100 {
public static void main(String[] args) {
//1.定义int变量sum,用来累加求和,初始值0
int sum = 0;

//2.使用for获取1-100之间的数字
for (int i = 1; i <= 100; i++) {
//2.1判断如果当前数字是偶数
if (i % 2 == 0) {
//把当前数字累加到求和变量sum中
sum += i;
}
}
//3.for循环结束,打印求和变量sum的值
System.out.println("1-100之间的偶数数字之和: "+sum);
System.out.println("-------------");

//1.定义int变量sum2,用来累加求和,初始值0
int sum2 = 0;

//2.使用for获取1-100之间的偶数数字
for (int j = 0; j <= 100; j++,j++/*j+=2*/) {
//2.1把当前数字(偶数)累加到求和变量sum2中
//System.out.println(j);
sum2 += j;
}
//3.for循环结束,打印求和变量sum的值
System.out.println("1-100之间的偶数数字之和: "+sum2);

}
}

for循环练习5:水仙花数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
需求:
键盘录入一个三位数字,输出该数字是否是水仙花数字?

解释:什么是水仙花数?
水仙花数,指的是一个三位数[100,999],个位、十位、百位的数字立方和等于原数
例如 153 3*3*3 + 5*5*5 + 1*1*1 = 27 + 125 + 1 = 153

实现步骤:
1.创建键盘录入Scanner类的对象(1.导包 2.创建)
2.获取键盘录入的一个三位整数数字,保存到int变量num中
3.使用if判断如果num中的数字是三位数字
3.1 计算num的个位,十位,百位 分别保存到3int变量ge(个位),shi(十位),bai(百位)中
3.2 计算个位,十位,百位数字的立方和,保存到int变量sum中
3.3 判断如果三位数字num 等于 每位数字的立方和sum,输出num是一个水仙花数字
3.4 判断如果三位数字num 不等于 每位数字的立方和sum,输出num不是一个水仙花数字
4.如果num中的数字不是三位数字,提示"你输入的不是三位数字,所以不可能是水仙花数字"

public class Demo05ISSXH {
public static void main(String[] args) {
//1.创建键盘录入Scanner类的对象(1.导包 2.创建)
Scanner sc = new Scanner(System.in);

//2.获取键盘录入的一个三位整数数字,保存到int变量num中
System.out.println("请录入一个三位整数数字: ");
int num = sc.nextInt();

//3.使用if判断如果num中的数字是三位数字
if (num >= 100 && num <= 999) {
//3.1 计算num的个位,十位,百位 分别保存到3个int变量ge(个位),shi(十位),bai(百位)中
int ge = num%10;//个位
int shi = num/10%10;//十位
int bai = num/100%10;//百位

System.out.println("个位: "+ge);
System.out.println("十位: "+shi);
System.out.println("百位: "+bai);

//3.2 计算个位,十位,百位数字的立方和,保存到int变量sum中
int sum = ge*ge*ge + shi*shi*shi + bai*bai*bai;

//3.3 判断如果三位数字num 等于 每位数字的立方和sum,输出num是一个水仙花数字
if(sum == num) {
System.out.println(num+"是一个水仙花数字....");
} else {
//3.4 判断如果三位数字num 不等于 每位数字的立方和sum,输出num不是一个水仙花数字
System.out.println(num+"不是一个水仙花数字....");
}

} else {
//4.如果num中的数字不是三位数字,提示"你输入的不是三位数字,所以不可能是水仙花数字"
System.out.println("你输入的不是三位数字,所以不可能是水仙花数字....哥屋恩....");
}
}
}

for循环练习6:水仙花数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
需求:
在控制台输出所有的“水仙花数”

解释:什么是水仙花数?
水仙花数,指的是一个三位数,个位、十位、百位的数字立方和等于原数
例如 153 3*3*3 + 5*5*5 + 1*1*1 = 27 + 125 + 1 = 153

实现步骤:
1.使用for循环获取所有的三位数字,每个数字保存到int变量num中
1.1计算num中数字的个位,十位,百位 分别保存到3int变量ge(个位),shi(十位),bai(百位)中
1.2计算个位,十位,百位数字的立方和,保存到int变量sum中
1.3判断如果三位数字num 等于 每位数字的立方和sum,输出该数字num

public class Demo06PrintSXH {
public static void main(String[] args) {
//1.使用for循环获取所有的三位数字,每个数字保存到int变量num中
for (int num = 100; num <= 999; num++) {

//1.1计算num中数字的个位,十位,百位 分别保存到3个int变量ge(个位),shi(十位),bai(百位)中
//123
int ge = num%10;//个位
int shi = num/10%10;//十位
int bai = num/100%10;//百位

//1.2计算个位,十位,百位数字的立方和,保存到int变量sum中
int sum = ge*ge*ge + shi*shi*shi + bai*bai*bai;
//1.3判断如果三位数字num 等于 每位数字的立方和sum,输出该数字num
if(sum == num) {
System.out.println(num);
}
}
}
}

for循环练习7:水仙花数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
需求:
在控制台输出所有的“水仙花数”及总个数

解释:什么是水仙花数?
水仙花数,指的是一个三位数,个位、十位、百位的数字立方和等于原数
例如 153 3*3*3 + 5*5*5 + 1*1*1 = 27 + 125 + 1 = 153

实现步骤:
1.定义int变量count,初始值0,作用是统计水仙花数字的个数
2.使用for循环遍历获取所有的三位数字,每个数字保存到int变量num中
2.1计算num中数字的个位,十位,百位 分别保存到3int变量ge(个位),shi(十位),bai(百位)中
2.2计算个位,十位,百位数字的立方和,保存到int变量sum中
2.3判断如果三位数字num 等于 每位数字的立方和sum,输出该数字num,同时计数器count的值增加1
3.for循环结束后,打印count的值

public class Demo07CountSXH {
public static void main(String[] args) {
//1.定义int变量count,初始值0,作用是统计水仙花数字的个数
int count = 0;

//2.使用for循环遍历获取所有的三位数字,每个数字保存到int变量num中
for (int num = 100; num <= 999; num++) {
//2.1计算num中数字的个位,十位,百位 分别保存到3个int变量ge(个位),shi(十位),bai(百位)中
int ge = num%10;//个位
int shi = num/10%10;//十位
int bai = num/100%10;//百位
//2.2计算个位,十位,百位数字的立方和,保存到int变量sum中
//2.3判断如果三位数字num 等于 每位数字的立方和sum
if((ge*ge*ge+shi*shi*shi+bai*bai*bai) == num) {
//输出该数字num
System.out.println(num);
//同时计数器count的值增加1
count++;
}
}
//3.for循环结束后,打印count的值
System.out.println("水仙花数字总共有: "+count+" 个");
}
}

计数思想:

image-20200426113750867

for循环练习8:数据反转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 数据反转
public class Demo07CountSXH {
public static void main(String[] args) {
/*
循环中定义变量min=0最小索引
max=arr.length‐1最大索引
min++,max‐‐
*/
int[] arr = {1,2};
for (int min = 0, max = arr.length - 1; min <= max; min++, max--) {
//利用第三方变量完成数组中的元素交换
int temp = arr[min];
arr[min] = arr[max];
arr[max] = temp;
}
}
}

while

算法有限性:不要忘记控制变量语句,否则会死循环

while循环语句介绍

1
2
3
4
5
6
7
8
9
10
11
1.while循环格式:
初始化表达式1;
while(布尔表达式2) {
循环体3;
步进表达式4;
}
其它语句;

2.执行流程:
1,2(循环条件: true),3,4 --> 2(循环条件: true),3,4 --> ... -->
直到布尔表达式2(循环条件: false),结束循环,执行循环后面的其它语句

图解:

image-20220728091249076

while循环练习1:循环打印

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
需求:
在控制台输出5次HelloWorld
public class Demo01WhileHello {
public static void main(String[] args) {
//使用for
for (int i = 1; i <= 5; i++) {
System.out.println("HelloWorld...."+i);
}
System.out.println("-------------");

//使用while
int j = 1;
while(j<=5) {//j: 1,2,3,4,5 6<=5 --> false --> 结束while循环
System.out.println("HelloWorld~~~~~"+j);
j++;
}
System.out.println("main......end.....");
}
}


while循环练习2:珠穆朗玛峰

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
需求:
世界最高山峰是珠穆朗玛峰(8844.43米=8844430毫米),假如我有一张足够大的纸,它的厚度是0.1毫米。
请问,我折叠多少次,可以折成珠穆朗玛峰的高度?
折纸(折叠后的厚度是原有厚度的2倍,而不是平方的关系):
原来: 0.1
第一次: 0.2
第二次: 0.4
第三次: 0.8
第四次: 1.6
...

实现步骤:
0.定义2double变量zf(珠峰的高度)和paper(纸张的厚度),并根据题目需求进行初始化
1.定义int变量count,初始值0,作用用来记录折叠纸张的次数
2.使用while循环,完成折叠纸张最终厚度达到珠峰的高度
2.1循环条件: 只要折叠后的纸张厚度 小于 珠峰的高度 就必须继续折叠纸张
2.2循环体: 折叠纸张(原有厚度的2倍: paper = paper*2;) 计数器count增加1
3.while循环结束打印count的值
public class Demo02WhileZFCount {
public static void main(String[] args) {
//0.定义2个double变量zf(珠峰的高度)和paper(纸张的厚度),并根据题目需求进行初始化
double zf = 8844430;//珠峰的高度
double paper = 0.1;//纸张的厚度

//1.定义int变量count,初始值0,作用用来记录折叠纸张的次数
int count = 0;

//2.使用while循环,完成折叠纸张最终厚度达到珠峰的高度
//2.1循环条件: 只要折叠后的纸张厚度 小于 珠峰的高度 就必须继续折叠纸张
//2.2循环体: 折叠纸张(原有厚度的2倍: paper = paper*2;) 计数器count增加1
while (paper < zf) {
//折叠纸张(原有厚度的2倍: paper = paper*2;)
paper *= 2;
//计数器count增加1
count++;
System.out.println("第"+count+"次折叠后纸张总厚度: "+paper);
}

//3.while循环结束打印count的值
System.out.println("总共折叠纸张的次数: "+count);
//1.34217728E7: 1.34217728*10^7 --> 13421772.8
//珠峰高度: 8844430
System.out.println("最后折叠纸张的厚度: "+paper);
}
}

do-while

至少执行一次(特别适合控制台打印菜单的应用场景)

do-while循环语句介绍

1
2
3
4
5
6
7
8
9
10
1.do-while循环格式:
初始化表达式1;
do {
循环体3;
步进表达式4;
}while(布尔表达式2);

2.执行流程:
1,3,4 --> 2(循环条件: true),3,4 --> ... -->
直到布尔表达式2(循环条件: false),结束循环,执行循环后面的其它语句

图解:

image-20220728091315609

do-while循环练习1

1
2
3
4
5
6
7
8
9
10
11
12
13
do-while循环练习:
在控制台输出5次HelloWorld

public class Demo01DoWhileHello {
public static void main(String[] args) {
int i = 1;
do {
System.out.println("HelloWorld~~~~~"+i);
i++;
}while(i<=5);//2,3,4,5 6<=5: false,结束do-while循环,执行后面的语句
System.out.println("main....end....");
}
}

循环语句的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
三种循环的区别总结
1.建议使用的顺序:for,while,do-while
2.循环次数确定的话,建议使用for,循环次数不确定建议使用while 【后面有使用场景】
循环次数不确定需要先写成死循环的格式【while好看】 --------后天讲解
3.do-while循环来讲的话,至少执行一次
4.whiledo-while循环而言,循环结束后,初始化条件中定义的变量可以继续使用,
但是for循环的不能使用(在for循环内部定义初始化语句)

public class Demo02Diff {
public static void main(String[] args) {
//3.do-while循环来讲的话,至少执行一次

//for循环: 先判断条件,后执行循环体
//for循环第一次布尔表达式都不成立(false): 循环体一次都不执行
//第一次: i>5 --> 3>5 --> false 不执行循环体,直接执行for循环后面的输出语句
for (int i = 3; i > 5; i++) {
System.out.println("Hello...for...");
}
System.out.println("for...end...");

//while循环: 先判断条件,后执行循环体
//while循环第一次布尔表达式都不成立(false): 循环体一次都不执行
//第一次: j>5 --> 3>5 --> false 不执行循环体,直接执行while循环后面的输出语句
int j = 3;
while (j > 5) {
System.out.println("Hello...while...");
j++;
}
System.out.println("while...end...");

//do-while循环: 先执行循环体,再判断条件
//do-while循环第一次布尔表达式都不成立(false): 循环体会至少执行一次(先执行,后判断条件)
//第一次: 定义int变量k的值3,接着执行{}中的循环体,k的值变成4
//再执行判断条件k>5 --> 4>5 --> false 结束do-while循环执行do-while后面的输出语句
int k = 3;
do{
System.out.println("Hello...do-while...");
k++;//4
} while(k>5);//k>5 --> 4>5 --> false 结束do-while循环执行do-while后面的输出语句
System.out.println("do-while...end...");
}
}

public class Demo03Diff {
public static void main(String[] args) {
//4.while和do-while循环而言,循环结束后,初始化条件中定义的变量可以继续使用,
//但是for循环的不能使用(在for循环内部定义初始化语句)
for (int i = 1; i <= 3; i++) {
System.out.println("Hello...for...in..."+i);
}
//错误: i是在for循环内部定义,只能在for循环内部使用
//出了for循环,就不可以继续使用
//System.out.println("Hello...for...out..."+i);
System.out.println("Hello...for...out...");

//while循环
int j = 1;
while (j <= 3) {
System.out.println("Hello...while...in..."+j);
j++;
}
//while循环: 初始化语句中定义的变量,while循环结束后仍然可以使用
System.out.println("Hello...while...out..."+j);

//do-while循环
int k = 1;
do{
System.out.println("Hello...do-while...in..."+k);
k++;
} while(k<=3);
//do-while循环: 初始化语句中定义的变量,do-while循环结束后仍然可以使用
System.out.println("Hello...do-while...out..."+k);
}
}


死循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*
死循环
1.概念: 永不休止的循环
2.分类:
(1)for循环的死循环格式 for芬芬
for(;;){...}

for (int j = 1; j > 0; j++) {
j--;
}

(2)while循环的死循环格式 建议使用
while(true){...}

int i = 0;
while (i < 10) {
// 缺少控制变量语句
}

(3)do-while循环的死循环格式
do{
...
}while(true);
*/
public class Demo04DeadLoop {
public static void main(String[] args) {
//for循环
/*for (;true;) {
System.out.println("Hello");
}*/
//for循环的死循环格式
//不写布尔表达式: 默认就是true
/*for (;;) {
System.out.println("Hello");
}*/

//while循环的死循环格式
/*int i = 0;
while(i<3) {
System.out.println("Hello");
}*/
/*while (true) {
System.out.println("Hello");
}*/

//do-while循环的死循环格式
/*int i = 0;
do {
System.out.println("Hello");
}while(i<3);*/
do {
System.out.println("Hello");
}while(true);
}
}

循环跳转

break的介绍

1
2
3
4
5
break的使用场景:
1.使用在switch语句中,用来结束switch语句,执行switch语句后面的其它语句
2.使用在循环中,用来结束循环(1.本次循环的循环体中break后面的代码不再执行 2.剩余次数的循环也不再执行),
执行循环后面的其它语句
3.break不能使用在除switch和循环语句以外的其它位置

break的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Demo01Break {
public static void main(String[] args) {
System.out.println("顾客获取到了购买的四个包子..........");
for (int num = 1; num <= 4; num++) {
/*
当num的值为2时,num == 2 --> true,if后面()中是true,执行if后面{}中的内容,
首先: 执行输出语句
其次: 执行break,一旦执行break,本次循环的循环体中break后面的代码不再执行,
剩余次数的循环也不再执行,直接从循环中跳出到循环后面的其它代码继续执行

*/
if (num == 2) {
System.out.println("发现2号包子上有个大家伙(小强),2号(及剩余所有)包子不能吃了,找老板投诉");
break;
}
System.out.println("顾客吃第"+num+"个包子......");
}
System.out.println("顾客投诉: 这是神马包子,岂有此理.老板: 非常抱歉,赔偿100000元~~~~~");
}
}

图解分析:

image-20200514092950990

break的练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Demo02Break {
public static void main(String[] args) {

for (int i = 1; i <= 10; i++) {
/*
当i的值是5的时候, i % 5 == 0 --> 5%5 == 0 --> true,
if后面()中是true,执行if后面{}中的内容(只有break),
一旦执行break,本次循环的循环体中break后面的代码不再执行,
而且剩余次数的循环也不再执行,直接从循环中跳出(结束循环)到循环后面的其它语句
*/
if (i % 5 == 0) {
break;
}
System.out.println("HelloWorld~~~~~~~~~~~~~~~" + i);
}
System.out.println("main....end....");
}
}

图解分析:

image-20200427094428938

break跳出嵌套循环

嵌套循环内层使用break只能跳出内层,要跳出外层需添加标记

默认跳出包裹此关键字最近的一层循环

1
2
3
4
5
6
7
a: while() {
for() {
if() {
break a;
}
}
}

continue的介绍

1
2
3
continue的使用场景:
1.只能使用在循环中,作用是提前结束本次循环,继续进行下一次循环
2.不能使用在除循环结构中的其它位置

continue的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Demo03Continue {
public static void main(String[] args) {
System.out.println("顾客获取到了购买的四个包子..........");
for (int num = 1; num <= 4; num++) {
/*
当num的值为2时,num == 2 --> true,if后面()中是true,执行if后面{}中的内容,
首先: 执行输出语句
其次: 执行continue,一旦执行continue,本次循环的循环体中continue后面的代码不再执行,
继续执行下一次循环的步进表达式
总结: continue的作用提前结束本次循环,继续进行下一次循环

*/
if (num == 2) {
System.out.println("把第2个包子弄脏了,不能吃第2个包子了,继续吃其它包子...");
continue;
}
System.out.println("顾客吃第"+num+"个包子......");
}
System.out.println("找老板结账,交钱400块,老板说: 欢迎下次光临....");
}
}

图解分析:

image-20200514100702686

continue的练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Demo04Continue {
public static void main(String[] args) {
for (int i = 1; i <= 10; i++) {
/*
当i的值是5和10的时候, i % 5 == 0 --> true,
if后面()中是true,执行if后面{}中的内容(只有continue),
一旦执行continue,本次循环的循环体中continue后面的代码不再执行,
继续执行下一次循环的步进表达式
总结: continue的作用提前结束本次循环,继续进行下一次循环(步进表达式)
*/
if (i % 5 == 0) {
continue;
}
System.out.println("HelloWorld....." + i);
}
System.out.println("main~~~~~~~end~~~~~~~~");
}

}

图解分析:

image-20200514122234145

return

return:意味着方法结束,后面的代码不执行。不能说return是专门结束循环的,而是方法结束了,循环自然也结束了,不管多少层循环

循环嵌套

概念和格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1.概念: 使用一个循环作为另外一个循环的循环体,外面的循环叫做外层循环,里面的循环叫做内层循环
2.格式(for嵌套):
for(初始化表达式1;布尔表达式2;步进表达式7){//外层循环

for(初始化表达式3;布尔表达式4;步进表达式6) {//内层循环
内层循环的循环体5;
}

}
其它语句;

3.执行流程:
1,2(true:外层循环条件) -->
3,4(true:内层循环条件),5,6 --> 4(true:内层循环条件),5,6
--> 直到4(false:内层循环条件),结束内层循环
7,2(true:外层循环条件) -->
3,4(true:内层循环条件),5,6 --> 4(true:内层循环条件),5,6
--> 直到4(false:内层循环条件),结束内层循环
...
直到2(false:外层循环条件),结束外层循环,执行外层循环后面的其它语句

执行流程图解:

image-20220728091554983

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
1.需求:
(1)教练安排运动员跑圈
(2)教练总共安排3次,每次跑3

2.问题:
1.外层循环 int i = 1 执行几次? 1
2.内层循环 int j = 1 执行几次? 3
3.内层循环的循环体执行几次?
外层循环的次数 * 内层循环每遍执行的次数 = 3 * 3 = 9
3.总结:
外层循环执行1次,内层循环执行完整的(从初始化表达式开始)一遍

public class Demo01ForFor {
public static void main(String[] args) {
/*
外层循环第一次: i = 1 i<=3 --> 1<=3 --> true --> 执行外层循环的循环体
内层循环:
j: 1,2,3(3次执行内层循环的输出语句),
4 j<=3 --> 4<=3 --> false --> 结束内层循环,执行外层循环的步进表达式i++,i: 2

外层循环第二次: i = 2 i<=3 --> 2<=3 --> true --> 执行外层循环的循环体
内层循环:
j: 1,2,3(3次执行内层循环的输出语句),
4 j<=3 --> 4<=3 --> false --> 结束内层循环,执行外层循环的步进表达式i++,i: 3

外层循环第三次: i = 3 i<=3 --> 3<=3 --> true --> 执行外层循环的循环体
内层循环:
j: 1,2,3(3次执行内层循环的输出语句),
4 j<=3 --> 4<=3 --> false --> 结束内层循环,执行外层循环的步进表达式i++,i: 4

外层循环第四次: i = 4 i<=3 --> 4<=3 --> false --> 结束外层循环,执行外层循环后面的其它语句

*/
for(int i = 1;i<=3;i++){//外层循环: 控制趟/遍数
System.out.println("教练第"+i+"次说: 你给我跑跑3圈");
for(int j = 1;j<=3;j++){//内层循环: 控制每趟/遍执行的次数
System.out.println((" 运动员跑第"+i+"次第" + j + "圈"));
}
}
System.out.println("main...end...");
}
}

循环嵌套概念图解:

image-20200427110457429

打印月份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
需求:
使用嵌套循环,打印2021年至2023年月份,格式:xxxx年x月
/*
需求:
使用嵌套循环,打印2021年至2023年月份,格式:xxxx年x月

总结:
外层循环执行1次,内层循环执行完整的(从初始化表达式开始)一遍
*/
public class Demo02ForForMonth {
public static void main(String[] args) {
for (int year = 2021; year <= 2023; year++) {//外层循环: 控制年份 2021 2022 2023 3次

for (int month = 1; month <= 12; month++) {//内层循环: 控制每年的月份,每年都有12个月,都是从1月开始
//1,2...12: 12次
System.out.println(year + "年" + month + "月");//执行次数:3*12 = 36次
}
}
System.out.println("main....end....");
}
}

图解分析:

image-20200427113418654

模拟钟表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
需求:
模拟钟表的时针和分针
时针(外层循环)走一个格,分钟(内层循环)走一圈
对应:
外层循环执行一次,内层循环执行完整的一遍

/*
需求:
模拟钟表的时针和分针
时针(外层循环)走一个格,分钟(内层循环)走一圈
对应:
外层循环执行一次,内层循环执行完整的一遍

*/
public class Demo03ForForClock {
public static void main(String[] args) {

for (int hour = 0; hour < 24; hour++) {//外层循环: 控制每天都有24小时

for (int minute = 0; minute < 60; minute++) {//内层循环: 控制每小时都有60分钟

System.out.println(hour+"点"+minute+"分");

}
}

//System.out.println("main....end...");
}
}

图解分析:

image-20200427114211716

方法

方法入门

内存:每个方法在被调用执行的时候,都会进入栈内存,并且拥有自己独立的内存空间,方法内部代码调用完毕之后,会从栈内存中弹栈消失

方法引入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/*
代码功能:模拟游戏中打怪物的场景

发现问题:
打怪物的代码是相同的,打了3次怪物,写了3次相同的代码,导致程序代码冗余,阅读性差

怎么解决问题呢?
1.能否将发射炮弹的代码,做成一个方法/功能
2.使用的时候直接调用即可
========================================================================
这个代码大家不用写,直接拷贝
========================================================================
*/
public class Demo01NoMethod {
/*
main是一个主方法,由JVM调用,是程序的入口
1.public static:修饰符,目前固定写法
2.void:返回值类型,表示方法内部的代码执行完毕,没有最终的结果,返回给调用者
3.main:方法名称:固定写法
4.String[] args:方法的参数
*/
public static void main(String[] args) {
System.out.println("游戏开始...");

System.out.println("看到了一个怪物...血牙野猪...");
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发炮弹结束");
System.out.println("...血牙野猪被打倒...");

System.out.println("...走啊走啊走啊走...");
System.out.println("看到了一个怪物...黄金虎鲨...");
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发炮弹结束");
System.out.println("...黄金虎鲨被打倒...");

System.out.println("...走啊走啊走啊走...");
System.out.println("看到了一个怪物...吞天巨狼...");
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发炮弹结束");
System.out.println("...吞天巨狼被打倒...");
System.out.println("...走啊走啊走啊走...");

System.out.println("游戏结束...");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*
代码功能:模拟游戏中打怪物的场景

发现问题:
打怪物的代码是相同的,打了3次怪物,写了3次相同的代码,导致程序代码冗余,阅读性差

怎么解决问题呢?
1.能否将发射炮弹的代码,做成一个方法/功能
2.使用的时候直接调用即可
========================================================================
这个代码大家不用写,直接拷贝
========================================================================

注意:
1.方法定义完毕后不调用不执行
2.调用格式:
方法名称(...);
3.方法可以调用任意多次
*/
public class Demo02UseMethod {
/*
main是一个主方法,由JVM调用,是程序的入口
1.public static:修饰符,目前固定写法
2.void:返回值类型,表示方法内部的代码执行完毕,没有最终的结果,返回给调用者
3.main:方法名称:固定写法
4.String[] args:方法的参数
*/
public static void main(String[] args) {
/*int num = 0;
System.out.println(num);
int[] arr = {10,20};
System.out.println(arr);*/
System.out.println("游戏开始...");

System.out.println("看到了一个怪物...血牙野猪...");

//调用方法,发射炮弹
fire();

System.out.println("...血牙野猪被打倒...");

System.out.println("...走啊走啊走啊走...");
System.out.println("看到了一个怪物...黄金虎鲨...");

//调用方法,发射炮弹
fire();

System.out.println("...黄金虎鲨被打倒...");

System.out.println("...走啊走啊走啊走...");
System.out.println("看到了一个怪物...吞天巨狼...");

//调用方法,发射炮弹
fire();

System.out.println("...吞天巨狼被打倒...");
System.out.println("...走啊走啊走啊走...");

System.out.println("游戏结束...");
}
/*
模拟main方法,定义一个发射炮弹的方法fire
*/
public static void fire() {
System.out.println("准备发射5发炮弹");
for (int i = 1; i <= 5; i++) {
System.out.println("发射第"+i+"发炮弹* * * *");
}
System.out.println("发射5发炮弹结束");

return ;//结束方法,返回到方法的调用处
}
}

图解:

image-20200516092757974

方法的概念和格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1.方法的概念:
就是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集。
将具有特殊功能的一段代码,使用大括号{}括起来,添加必要的修饰符,起个名字, 方便使用

2.方法的格式:
修饰符 返回值类型 方法名称(参数列表) {
功能代码;
return ;//如果返回值类型是void,建议省略不写
}

3.格式解释:
(1)修饰符: public static 目前固定写法,先记住
(2)返回值类型: 方法的功能代码执行完毕后,产生的需要返还给方法的调用者的结果数据的具体类型
目前定义的方法没有返回值,返回值类型固定写为void
(3)方法名称:
给方法起个名字(符合标识符的命名规范,小驼峰原则(第一个单词首字母小写,其它单词首字母大写)),方便使用
(4)参数列表: 目前没有参数,不需要写参数列表,但是必须保留小括号()
(5)功能代码: 完成特殊功能的一行/多行代码
(6)return ;:
a.结束方法
b.返回到方法的调用处

4.方法定义步骤:
1.明确返回值类型(有没有,什么类型)
2.明确方法名(起名字好难的说-。-)(根据方法的功能,见名知意)
3.明确参数列表(有没有,有几个,什么类型)

无返回值无参数方法的定义和调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
1.练习:
定义方法method,方法内部输出一句话"我是一个方法"

/*
无返回值无参数方法的定义和调用
无参数:
目前没有参数,不需要写参数列表,但是必须保留小括号()
无返回值:
目前定义的方法没有返回值,返回值类型固定写为void
方法内部没有数据返还给调用者,没有返回值,返回值类型固定写为void

1.练习:
定义方法method,方法内部输出一句话"我是一个方法"
2.注意:
(1)方法定义完毕后不调用不执行
(2)调用格式:
方法名称(...);
(3)方法可以调用任意多次
*/
public class Demo03Method {

public static void main(String[] args) {

System.out.println("main...start...");

//调用方法
method();

System.out.println("main...end...");

}

//定义方法method,方法内部输出一句话"我是一个方法"
public static void method() {

System.out.println("我是一个方法");

return ;//结束方法,返回到方法的调用处,建议省略
}
}

无返回值无参数方法的调用图解

image-20200516095454283

无返回值无参数的方法练习-打印数字是否是偶数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
需求:
定义一个方法,打印输出该方法内部的数据(方法内部定义的变量)是否是偶数

/*
无返回值无参数方法的定义和调用
无参数:
目前没有参数,不需要写参数列表,但是必须保留小括号()
无返回值:
目前定义的方法没有返回值,返回值类型固定写为void
方法内部没有数据返还给调用者,没有返回值,返回值类型固定写为void

1.练习:
定义一个方法,打印输出该方法内部的数据(方法内部定义的变量)是否是偶数

2.注意:
(1)方法定义完毕后不调用不执行
(2)调用格式:
方法名称(...);
(3)方法可以调用任意多次

练习中如果没有明确数据类型,默认int类型
*/
public class Demo01PrintOu {

public static void main(String[] args) {

System.out.println("main...start...");

//调用方法
printOu();

System.out.println("main...end...");

}

//定义一个方法,打印输出该方法内部的数据(方法内部定义的变量)是否是偶数
public static void printOu() {

int num = 12;

boolean result = (num%2==0) ? true : false;

System.out.println(num+"是偶数吗? "+result);

return ;//结束方法,返回到方法的调用处,建议省略
}
}

图解分析:

image-20200516101539927

无返回值无参数的方法练习-打印最大值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
需求:
定义一个方法,打印该方法内部的两个数据(方法内部定义的变量)的最大值
/*
无返回值无参数方法的定义和调用
无参数:
目前没有参数,不需要写参数列表,但是必须保留小括号()
无返回值:
目前定义的方法没有返回值,返回值类型固定写为void
方法内部没有数据返还给调用者,没有返回值,返回值类型固定写为void

1.练习:
定义一个方法,打印该方法内部的两个数据(方法内部定义的变量)的最大值

2.注意:
(1)方法定义完毕后不调用不执行
(2)调用格式:
方法名称(...);
(3)方法可以调用任意多次

练习中如果没有明确数据类型,默认int类型
*/
public class Demo02PrintMax {

public static void main(String[] args) {

System.out.println("main...start...");

//调用方法
printMax();

System.out.println("main...end...");
}

//定义一个方法,打印该方法内部的两个数据(方法内部定义的变量)的最大值
public static void printMax() {

int a = 100, b = 200;

int max = (a>b) ? a : b;

System.out.println("最大值: "+max);

return ;//结束方法,返回到方法的调用处,建议省略
}

}

图解:

image-20200516102543118

方法详解

方法的格式详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
1.方法的概念:
就是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集。
将具有特殊功能的一段代码,使用大括号{}括起来,添加必要的修饰符,起个名字, 方便使用

2.方法的格式:
修饰符 返回值类型 方法名称(数据类型1 变量名称1,数据类型2 变量名称2...) {
功能代码;
return 返回值;//如果return 后面 有具体的结果数据,不能省略return
}
注意:
(1)方法没有参数,不用写参数列表,但是必须保留小括号()
(2)方法内部没有返回值返还给调用者,返回值类型必须固定写为void

3.格式解释:
(1)修饰符: public static 目前固定写法,先记住
(2)返回值类型: 告诉方法的调用者,我方法结束后,给你一个什么类型的数据
方法的功能代码执行完毕后,产生的需要返还给方法的调用者的结果数据的具体类型
举例:
如果方法内部返回整数数字100,返回值类型写为int
如果方法内部返回小数数字6.6,返回值类型写为double
如果方法内部返回true/false,返回值类型写为boolean
(3)方法名称:
给方法起个名字(符合标识符的命名规范,小驼峰原则(第一个单词首字母小写,其它单词首字母大写)),方便使用

(4)参数列表: 你调用我这个方法时,需要给我几个什么样子的数据
就是在定义方法时,小括号()中定义了一个/多个变量
定义方法参数列表举例:
(int a): 调用方法时,必须传递给方法一个int类型的数据
(int a,int b): 调用方法时,必须传递给方法两个int类型的数据
(double a,double b): 调用方法时,必须传递给方法两个double类型的数据

(5)功能代码: 完成特殊功能的一行/多行代码
(6)return 返回值/结果数据;:
a.结束方法
b.把return 后面的返回值/结果数据,返还到方法的调用处

4.方法的理解(工厂/机器)
(1)生产汽车的工厂:
原材料: 发动机,变速箱,车架...
产出物: BMW750Li S600 ZT700
(2)榨汁机:
原材料: 水果,水,糖,冰块...
产出物: 果汁(苹果汁,桃汁,梨汁...)

原材料是进入工厂/机器的东西,相当于调用方法时传递的数据 参数列表
产出物是从工厂/机器中出来的东西,相当于调用方法后的返回值 返回值 --- 返回值类型

5.定义方法的三要素
(1)方法名称:
(2)参数列表:
(3)返回值类型:

6.注意:
(1)方法定义完毕后不调用不执行
(2)调用格式:
方法名称(参数1,参数2...);
(3)方法可以调用任意多次

带参数的方法练习-打印数字是否是偶数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
需求:
定义一个方法,该方法接收一个int参数,方法内部打印输出该数据是否是偶数
/*
带参数无返回值的方法练习
方法是否需要参数:
分析方法需求中是否具有不确定的东西

方法是否需要返回值:
如果方法需求中能够明确看到打印/输出二字,说明该方法不需要返回值,返回值类型固定写为void

1.练习:
定义一个方法,打印一个整数数字是否是偶数

2.三要素:
(1)方法名称: printOu
(2)参数列表: int num
(3)返回值类型: void

练习中如果没有明确数据类型,默认int类型
*/
public class Demo01PrintOu {

public static void main(String[] args) {

System.out.println("main...start...");

//调用方法: 传递的是常量
printOu(11 );

//调用方法方法: 传递变量
int a = 12;
printOu(a);

System.out.println("main...end...");

}

//定义一个方法,打印一个整数数字是否是偶数
/*
你调用我的方法printOu时,必须给我传递一个int类型的数据,
我printOu方法内部执行完毕后直接打印输出结果
你: 方法的调用者
我: 方法本身
有进无出
*/
public static void printOu(int num) {

boolean result = (num%2==0) ? true : false;

System.out.println(num+"是偶数吗? "+result);

return ;//结束方法,返回到方法的调用处
}
}

图解:

image-20200516112242265

带参数的方法练习-打印最大值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
需求:
定义一个方法用于打印两个int数中的较大数,数据来自于方法参数
/*
带参数无返回值的方法练习
方法是否需要参数:
分析方法需求中是否具有不确定的东西

方法是否需要返回值:
如果方法需求中能够明确看到打印/输出二字,说明该方法不需要返回值,返回值类型固定写为void

1.练习:
定义一个方法用于打印两个int数字中的较大数,数据来自于方法参数

2.三要素:
(1)方法名称: printMax
(2)参数列表: int a,int b
(3)返回值类型: void

练习中如果没有明确数据类型,默认int类型
*/
public class Demo02PrintMax {

public static void main(String[] args) {

System.out.println("main...start...");

//调用方法: 传递的是常量
printMax(10,20);

//调用方法方法: 传递变量
int m = 100;
int n = 200;
printMax(m,n);


System.out.println("main...end...");

}

//定义一个方法用于打印两个int数字中的较大数,数据来自于方法参数
/*
你调用我的方法printMax时,必须给我传递两个int类型的数据,
我printMax方法内部执行完毕后直接打印输出最大值的结果
你: 方法的调用者
我: 方法本身
*/
public static void printMax(int a, int b) {

int max = (a>b) ? a : b;

System.out.println("最大值: "+max);

return ;//结束方法,返回到方法的调用处
}
}

图解:

image-20200516113747053

带返回值的方法练习-获取数字是否是偶数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
需求:
定义一个方法,该方法接收一个int参数,判断该数据是否是偶数,并返回真假值
/*
有参数有返回值的方法练习
方法是否需要参数:
分析方法需求中是否具有不确定的东西

方法是否需要返回值:
如果方法需求中能够明确看到打印/输出二字,说明该方法不需要返回值,返回值类型固定写为void
如果方法需求中能够明确看到获取/返回/判断二字,说明该方法需要返回值,必须定义具体的返回值类型

1.练习:
定义一个方法,该方法接收一个int参数,判断该数据是否是偶数,并返回真假值

2.三要素:
(1)方法名称: getOu
(2)参数列表: int num
(3)返回值类型: boolean

练习中如果没有明确数据类型,默认int类型
*/
public class Demo01GetOu {

public static void main(String[] args) {

System.out.println("main...start...");

//调用方法: 传递的是常量
boolean result = getOu(11);

System.out.println("11是偶数吗? "+result);

//调用方法方法: 传递变量
int a = 12;
result = getOu(a);
System.out.println(a+"是偶数吗? "+result);

System.out.println("main...end...");

}

//定义一个方法,该方法接收一个int参数,判断该数据是否是偶数,并返回真假值
/*
你调用我的方法getOu时,必须给我传递一个int类型的数据,
我getOu方法内部执行完毕后,会返还给你一个boolean类型的数据
你: 方法的调用者
我: 方法本身
有进(参数)有出(返回值)
*/
//boolean: 告诉方法的调用者,方法功能代码执行完毕后,会返回数据的具体类型(会返回一个什么样子的数据)
public static boolean getOu(int num) {

boolean result = (num % 2 == 0) ? true : false;

return result;//结束方法,并且把result中的数据,返还给方法的调用处/者
}
}

图解分析:

image-20200516120122043

带返回值的方法练习-获取最大值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
需求:
设计一个方法可以获取两个int数的较大值,数据来自于参数
/*
有参数有返回值的方法练习
方法是否需要参数:
分析方法需求中是否具有不确定的东西

方法是否需要返回值:
如果方法需求中能够明确看到打印/输出二字,说明该方法不需要返回值,返回值类型固定写为void
如果方法需求中能够明确看到获取/返回/判断二字,说明该方法需要返回值,必须定义具体的返回值类型

1.练习:
设计一个方法可以获取两个int数的较大值,数据来自于参数

2.三要素:
(1)方法名称: getMax
(2)参数列表: int a,int b
(3)返回值类型: int

练习中如果没有明确数据类型,默认int类型
*/
public class Demo02GetMax {

public static void main(String[] args) {

System.out.println("main...start...");

//调用方法: 传递的是常量
int result = getMax(100,200);
System.out.println("100和200的最大值: "+result);

//调用方法方法: 传递变量
int a = 10, b = 20;
int max = getMax(a,b);
System.out.println(a+"和"+b+"的最大值: "+max);

System.out.println("main...end...");

}

//设计一个方法可以获取两个int数的较大值,数据来自于参数
/*
你调用我的方法getMax时,必须给我传递两个int类型的数据,
我getMax方法内部执行完毕后,会返还给你一个int类型的数据
你: 方法的调用者
我: 方法本身
有进(参数)有出(返回值)
*/
//int: 告诉方法的调用者,方法功能代码执行完毕后,会返回数据的具体类型(会返回一个什么样子的数据)
public static int getMax(int a, int b) {

int max = (a>b) ? a : b;

return max;//结束方法,并且把max中的数据,返还给方法的调用处/者
}
}


图解分析:

image-20200516142013131

方法的注意事项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*
方法的注意事项
1.方法不能嵌套定义(在定义方法的内部又定义了其它方法),可以调用其它方法
2.方法可以嵌套调用
3.返回值类型,必须要和 return 语句返回的数据的类型要匹配,否则编译失败 。
4.不能在 return 后面写代码, return 意味着方法结束,所有后面的代码永远不会执行,属于无效代码。
5.void表示无返回值,可以省略return,也可以单独的书写return,后面不加数据
*/
/*
方法的注意事项
1.方法不能嵌套定义(在定义方法的内部又定义了其它方法),可以调用其它方法
2.方法可以嵌套调用
3.返回值类型,必须要和 return 语句返回的数据的类型要匹配,否则编译失败 。
4.不能在 return 后面写代码, return 意味着方法结束,所有后面的代码永远不会执行,属于无效代码。
5.void表示无返回值,可以省略return,也可以单独的书写return,后面不加数据
*/
public class Demo01Notice {
public static void main(String[] args) {
//1.调用getNum方法,获取一个int数字
int num = getNum();
//2.调用printNum方法,打印一个int数字
printNum(num);

//方法的嵌套调用
//先执行getNum方法:获取一个整数数字
//再把整数数字交给printNum方法做打印输出
printNum(getNum());
}
//定义方法
public static void method() {
System.out.println("method....");
//错误: 方法不能嵌套定义方法
/*public static void show() {
System.out.println("show....");
}*/
}

//打印int数字
public static void printNum(int num) {
System.out.println(num);
}
//获取一个int数字
public static int getNum() {
return 100;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
方法的注意事项
1.方法不能嵌套定义(在定义方法的内部又定义了其它方法),可以调用其它方法
2.方法可以嵌套调用
3.返回值类型,必须要和 return 语句返回的数据的类型要匹配,否则编译失败 。
4.不能在 return 后面写代码, return 意味着方法结束,所有后面的代码永远不会执行,属于无效代码。
5.void表示无返回值,可以省略return,也可以单独的书写return,后面不能加数据,写个分号
*/
public class Demo02Notice {
public static void main(String[] args) {

}

//3.返回值类型,必须要和 return 语句返回的数据的类型要匹配,否则编译失败 。
public static double getDoubleNum() {
//return 6.6;//6.6就是一个double类型的数字
//return 6.6F;//6.6F是一个float类型的数字,可以自动类型提升为double类型
return 6;//6是一个int类型的数字,可以自动类型提升为double类型
}

//4.不能在 return 后面写代码, return 意味着方法结束,所有后面的代码永远不会执行,属于无效代码。
public static int getMax(int a,int b) {
if (a > b) {
return a;
} else {
return b;
}
//System.out.println("getMax...end...");//错误的,return后面不能写其他代码
}

//5.void表示无返回值,可以省略return,也可以单独的书写return,后面不能加数据,写个分号
public static void method() {
System.out.println("method....");
return ;//建议省略return
}
}

有返回值的方法调用方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
有返回值的方法调用方式
1.赋值调用: 把有返回值的方法的调用结果保存到对应的变量中 ----推荐使用----
数据类型 变量名称 = 方法名称(参数...);

2.输出/打印调用: 把有返回值的方法的调用结果直接交给输出语句
System.out.println(方法名称(参数...));

3.单独调用: 既不保存方法的结果,也没有对结果进行输出 -----不推荐使用,没有意义-----
方法名称(参数...);
*/
public class Demo01DYMethod {
public static void main(String[] args) {
System.out.println("main...start...");

//1.赋值调用: 把有返回值的方法的调用结果保存到对应的变量中
//数据类型 变量名称 = 方法名称(参数...);
int result = getSum(10,20);
//可以对结果数据做其它操作
//result *= 100;
System.out.println("和: "+result);

//2.输出/打印调用: 把有返回值的方法的调用结果直接交给输出语句
//System.out.println(方法名称(参数...));
System.out.println(getSum(100,200));

//3.单独调用: 既不保存方法的结果,也没有对结果进行输出
getSum(5,10);

System.out.println("main...end...");
}

//定义方法,获取2个int数字之和
public static int getSum(int a, int b) {
int sum = a + b;
return sum;
}
}

无返回值的方法调用方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
无返回值的方法调用方式

1.单独调用: 既不保存方法的结果,也没有对结果进行输出 只能采用单独调用
方法名称(参数...);

2.赋值调用: 把有返回值的方法的调用结果保存到对应的变量中 不能赋值调用
数据类型 变量名称 = 方法名称(参数...);

3.输出/打印调用: 把有返回值的方法的调用结果直接交给输出语句 不能输出调用
System.out.println(方法名称(参数...));
*/
public class Demo02DYMethod {
public static void main(String[] args) {
System.out.println("main...start...");
//1.单独调用: 既不保存方法的结果,也没有对结果进行输出
//方法名称(参数...);
printSum(10,20);

//2.赋值调用: 把有返回值的方法的调用结果保存到对应的变量中
//数据类型 变量名称 = 方法名称(参数...);
//int a = printSum(5,15);//错误的,int变量只能保存整数,但是printSum方法执行结束没有返回任何结果数据
//void a = printSum(5,15);//错误的,void根本不是数据类型

//3.输出/打印调用: 把有返回值的方法的调用结果直接交给输出语句
//System.out.println(方法名称(参数...));
//System.out.println(printSum(3,2));//错误: 因为printSum方法执行完毕后,没有任何结果返回

System.out.println("main...end...");
}

//定义方法,打印2个int数字之和
public static void printSum(int a, int b) {
int sum = a + b;
System.out.println("和: "+sum);
return ;//结束方法,返回到方法的调用处,注意没有带回任何数据
}
}

形式参数和实际参数的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*
形式参数和实际参数的区别
1.形式参数:
(1)概念: 定义方法时()中定义的参数(定义变量),叫做形式参数
(2)特点:
a.定义形式参数的时候,是没有值的
b.当调用该方法时,形式参数才会有值

2.实际参数:
(1)概念: 调用方法时()中给出的参数(常量/变量),叫做实际参数
(2)特点:
a.调用方法时,()中写的数据(常量/变量)
b.必须要有值才可以
*/
public class Demo03ParamDiff {
public static void main(String[] args) {
System.out.println("main...start...");
/*
2.实际参数:
(1)概念: 调用方法时()中给出的参数(常量/变量),叫做实际参数
(2)特点:
a.调用方法时,()中写的数据(常量/变量)
b.必须要有值才可以
*/
//调用方法: 传递常量
printSum(10,20);//10,20叫做实际参数

//调用方法: 传递变量
int m = 100,n = 200;

printSum(m,n);//m,n叫做实际参数


System.out.println("main...end...");
}

/*
1.形式参数:
(1)概念: 定义方法时()中定义的参数(定义变量),叫做形式参数
(2)特点:
a.定义形式参数的时候,是没有值的
b.当调用该方法时,形式参数才会有值
*/
//定义方法,打印2个int数字之和
public static void printSum(int a, int b) {
int sum = a + b;
System.out.println("和: "+sum);
return ;//结束方法,返回到方法的调用处,注意没有带回任何数据
}
}

image-20200516151320201

image-20200516151436471

方法重载

一个类/接口中,方法名相同,参数不同(个数,顺序,类型)的方法,与返回值无关

方法重载的引入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
需求:
1.定义一个获取两个int数字之和的方法
2.定义一个获取三个int数字之和的方法
3.定义一个获取两个double数字之和的方法
4.定义一个获取三个double数字之和的方法
定义一个获取两个int数字之和的方法
三要素:
1.方法名称: getTwoIntNumSum
2.参数列表: int a,int b
3.返回值类型: int

发现问题:
以下四个方法都是完成求和功能,但是参数列表是互不相同的,
但是我们给每个方法起了一个相当之复杂的名字,
导致程序员学习和使用方法的成本增加(记不住,太复杂)

解决方案:
方法重载
public class Demo01MethodProblem {
public static void main(String[] args) {
//打印/输出调用方法: 传递常量
System.out.println(getTwoIntNumSum(10,20));
System.out.println(getThreeIntNumSum(10,20,30));
System.out.println(getTwoDoubleNumSum(10.0,20.0));
System.out.println(getThreeDoubleNumSum(10.0,20.0,30.0));
}

//1.定义一个获取两个int数字之和的方法
public static int getTwoIntNumSum(int a, int b) {
return a + b;
}

//2.定义一个获取三个int数字之和的方法
public static int getThreeIntNumSum(int a, int b,int c) {
return a + b + c;
}

//3.定义一个获取两个double数字之和的方法
public static double getTwoDoubleNumSum(double a, double b) {
return a + b;
}

//4.定义一个获取三个double数字之和的方法
public static double getThreeDoubleNumSum(double a, double b,double c) {
return a + b + c;
}
}

方法重载的概念

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
方法重载
1.概念:
在同一个类中,多个功能相同,但是参数列表不同的多个方法,可以使用相同的名称,这种多个同名不同参的方法,
可以同时存在一个类中的现象,就叫做方法重载

比如:
比如某个类中已经有了一个名称为method的方法,还可以再定义名称为method的方法,
但是要求这些名称为method的方法的参数列表必须不同

2.作用/目的:
(1)减少程序员的学习和使用成本(原来需要记住四个名称复杂的方法,现在只需要记住一个名称简单的方法)
(2)减少了方法名称的数量

3.调用
(1)根据名称找到对应的方法
(2)根据参数的数量找到对应的方法
(3)根据参数的类型确定最终要调用的方法
(首先: 做类型完全匹配 其次: 完全匹配的找不到,再做自动类型提升的匹配)

public class Demo02MethodOverLoad {
public static void main(String[] args) {
//打印/输出调用方法: 传递常量
System.out.println(getSum(10,20));
System.out.println(getSum(10,20,30));
System.out.println(getSum(10.0,20.0));
System.out.println(getSum(10.0,20.0,30.0));
}

//1.定义一个获取两个int数字之和的方法
public static int getSum(int a, int b) {
System.out.println("...两个int.....");
return a + b;
}

//2.定义一个获取三个int数字之和的方法
public static int getSum(int a, int b,int c) {
System.out.println("...三个int.....");
return a + b + c;
}

//3.定义一个获取两个double数字之和的方法
public static double getSum(double a, double b) {
System.out.println("...两个double.....");
return a + b;
}

//4.定义一个获取三个double数字之和的方法
public static double getSum(double a, double b,double c) {
System.out.println("...三个double.....");
return a + b + c;
}
}

方法重载的注意事项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
方法重载中参数列表不同有哪些情况?
1.参数数量不同
2.参数类型不同
3.多个类型,顺序不同
public class Demo03OverLoadNotice {
public static void main(String[] args) {
method(10,10.0);
}

//1.此方法只有一个int类型参数
public static void method(int a) {

}
//2.此方法只有两个int类型参数
//方法2和方法1参数的数量是不同的,可以构成重载
public static void method(int a,int b) {

}
//3.此方法只有一个double类型参数
//方法3和方法2参数的数量是不同的,可以构成重载
//方法3和方法1参数虽然都是只有一个,但是类型不同,可以构成重载
public static void method(double a) {

}

//4.此方法有一个int类型参数和一个double类型参数
public static void method(int a,double b){

}
//5.此方法有一个double类型参数和一个int类型参数
//方法5和方法4,虽然参数都是2个,但是类型的顺序不同
public static void method(double a,int b){

}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
方法重载与哪些因素无关?
1.与参数的名称无关
2.与返回值类型无关
3.与修饰符无关

总结:
在多个方法同名的前提下,
只看多个方法的参数(除了名称以外)有区别,就构成重载

public class Demo04OverLoadNotice {
public static void main(String[] args) {

}

//1.此方法只有一个int类型参数
public static void method(int a) {

}
//2.此方法只有一个int类型参数
//方法2和方法1,只有参数的名称不同,无法构成重载
/*public static void method(int num) {

}*/
//3.此方法只有一个int类型参数
//方法3和方法1,只有返回值类型不同,无法构成重载
/*public static int method(int a) {
return 0;
}*/

//4.此方法只有一个int类型参数
//方法4和方法1,只有修饰符不同,无法构成重载
/*void method(int a) {

}*/
}

方法重载的练习-比较两个数据是否相等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
需求:
使用方法重载的思想,设计比较两个数据是否相等的方法,兼容全整数类型(byte,short,int,long

实现步骤:
1.使用方法重载的思想,定义比较两个byte数据的方法compare
2.使用方法重载的思想,定义比较两个short数据的方法compare
3.使用方法重载的思想,定义比较两个int数据的方法compare
4.使用方法重载的思想,定义比较两个long数据的方法compare
5.分别调用以上四个方法

使用方法重载的思想,定义比较两个byte数据是否相同的方法compare
三要素:
1.方法名称: compare
2.参数列表: byte a,byte b
3.返回值类型: boolean
public class Demo05OverLoadTest {
public static void main(String[] args) {
//5.分别调用以上四个方法
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));
}

//1.使用方法重载的思想,定义比较两个byte数据的方法compare
public static boolean compare(byte a, byte b) {
System.out.println("...两个byte...");
boolean result = (a == b) ? true : false;
return result;
}

//2.使用方法重载的思想,定义比较两个short数据的方法compare
public static boolean compare(short a, short b) {
System.out.println("...两个short...");
boolean result;
if (a == b) {
result = true;
} else {
result = false;
}
return result;
}

//3.使用方法重载的思想,定义比较两个int数据的方法compare
public static boolean compare(int a, int b) {
System.out.println("...两个int...");
if (a == b) {
return true;
} else {
return false;
}
}

//4.使用方法重载的思想,定义比较两个long数据的方法compare
public static boolean compare(long a, long b) {
System.out.println("...两个long...");
return a == b;
}
}

方法的参数传递

方法参数传递

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
参数传递:
可以理解当我们要调用一个方法时,我们会把指定的数值,传递给方法中的参数(定义方法时()中定义的变量),
这样方法中的参数就拥有了这个指定的值,可以使用该值,在方法中运算了。这种传递方式,我们称为参数传递。

形式参数: 定义方法时,()中定义的的变量
实际参数: 调用方法时,()中传入给方法的数值/变量

/*
注意:
1.使用=进行赋值的特点:
把基本类型变量a的值赋值给基本类型变量b时,其实是把a中的值复制一份给变量b,
之后不管如何修改变量b中的值,都不会影响变量a中的值

2.变量的作用范围:
方法内部定义的变量只在所定义的方法内有效(可以使用),出了方法的作用范围,就不能使用了
局部变量: 方法内部定义的变量或者方法定义时()中定义的变量

*/
public class Demo01Var {
public static void main(String[] args) {
//定义int变量a,并初始化
int a = 20;

//定义int变量b,未初始化
int b;

b = a;//把变量a中的值赋值给变量b

System.out.println("a="+a);//20
System.out.println("b="+b);//20

b = b*10;

System.out.println("a="+a);//20
System.out.println("b="+b);//200

method();

//System.out.println(num);//错误: num是在method方法内部定义,只在method方法内部有效
}

public static void method(/*int m*/) {
int num = 100;
System.out.println(num);
//System.out.println(a);//错误: a是在main方法内部定义,只在main方法内部有效
}
}

图解:

image-20200504104632367

基本类型作为方法参数传递

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*
基本数据类型作为方法参数
注意:
1.基本类型变量: 保存的是具体的数据值
2.基本类型变量作为形式参数,
形式参数的改变,不会影响实际参数


基本类型变量作为形式参数:
定义方法时,()中定义的参数属于基本类型

不会影响实际参数: 调用方法时,()中给出的参数
*/
public class Demo02BaseVar {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("ms...a="+a);//10
System.out.println("ms...b="+b);//20
//调用方法
change( a , b );
System.out.println("me...a="+a);//10
System.out.println("me...b="+b);//20
}

public static void change(int a, int b) {
System.out.println("cs...a="+a);//10
System.out.println("cs...b="+b);//20
a = a*10;
b = b*10;
System.out.println("ce...a="+a);//100
System.out.println("ce...b="+b);//200
}
}

图解:

image-20200504105826431

image-20200518111321501

引用类型作为方法参数传递

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*
引用数据类型作为方法参数
注意:
1.引用类型变量: 保存的是对象在堆内存空间的地址值,进行参数传递的时候,传递的也是地址值
2.引用类型变量作为形式参数,通过形式参数找到对应的堆内存空间,修改堆内存空间的内容之后,
通过实际参数看到的一定是修改后的堆内存空间的内容

引用类型作为形式参数,形式参数的改变,会影响实际参数

数组:
1.数组也是一种引用类型: 数组名称保存的也是数组在堆内存空间的地址值
2.数组作为方法参数或者返回值: 传递的都是数组在堆内存空间的地址值

*/
public class Demo03RefVar {
public static void main(String[] args) {
int[] arr = { 10 , 20 };
//System.out.println(arr);//数组名称: 保存数组在内存中的地址值[I@1540e19d
System.out.println("ms...arr[0]="+arr[0]);//10
System.out.println("ms...arr[1]="+arr[1]);//20
//调用方法
change( arr );
System.out.println("me...arr[0]="+arr[0]);//100
System.out.println("me...arr[1]="+arr[1]);//200
}

public static void change(int[] arr ) {
System.out.println("cs...arr[0]="+arr[0]);//10
System.out.println("cs...arr[1]="+arr[1]);//20
arr[0] = arr[0]*10;
arr[1] = arr[1]*10;
System.out.println("ce...arr[0]="+arr[0]);//100
System.out.println("ce...arr[1]="+arr[1]);//200
}
}

图解:

image-20200518113950171

方法的练习

数组遍历练习(不定义方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
需求(先不定义方法):
设计一个方法用于数组遍历(打印数组元素),
要求遍历的结果是在一行上的。例如:[11, 22, 33, 44, 55]

举例:
原数组: {11,22,33,44,55}
打印格式:[11, 22, 33, 44, 55]
实现步骤:
1.定义int数组array,并初始化
2.打印"[",不换行
3.使用for循环遍历数组
3.1打印数组当前元素,不换行
3.2如果步骤3.1中打印的元素不是最后一个元素,则需要打印", ",不换行
4.打印"]",可以换行也可以不换行

问题:
并没有把按照指定格式打印数组的功能定义成方法,
导致有多少个数组需要按照指定格式打印,就需要重复性的写几遍同样的代码

解决方案:
定义方法,实现数组按照指定格式打印
public class Demo01PrintArray {
public static void main(String[] args) {
//1.定义int数组array,并初始化
int[] array = {11,22,33,44,55};
//2.打印"[",不换行
System.out.print("[");

//3.使用for循环遍历数组
for (int i = 0; i < array.length; i++) {
//3.1打印数组当前元素,不换行
System.out.print(array[i]);
//3.2如果步骤3.1中打印的元素不是最后一个元素
if(i != array.length-1) {
//则需要打印", ",不换行
System.out.print(", ");
}
}

//4.打印"]",可以换行也可以不换行
System.out.println("]");

System.out.println("------------------");
array = new int[] {100,200,300,500,800,900};

//2.打印"[",不换行
System.out.print("[");

//3.使用for循环遍历数组
for (int i = 0; i < array.length; i++) {
//3.1打印数组当前元素,不换行
System.out.print(array[i]);
//3.2如果步骤3.1中打印的元素不是最后一个元素
if(i != array.length-1) {
//则需要打印", ",不换行
System.out.print(", ");
}
}

//4.打印"]",可以换行也可以不换行
System.out.println("]");
}
}

数组遍历练习(定义方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
需求(定义方法):
设计一个方法用于int数组遍历(打印数组元素),
要求遍历的结果是在一行上的。例如:[11, 22, 33, 44, 55]

举例:
原数组: {11,22,33,44,55}
打印格式:[11, 22, 33, 44, 55]

定义方法,用来遍历int数组
三要素:
1.方法名称: printArray
2.参数列表: int[] array
3.返回值类型: void

打印int数组方法printArray的实现步骤
1.打印"[",不换行
2.使用for循环遍历数组
2.1打印数组当前元素,不换行
2.2如果步骤2.1中打印的元素不是最后一个元素,则需要打印", ",不换行
3.打印"]",可以换行也可以不换行

main方法的实现步骤
1.定义int数组array,并进行初始化
2.调用printArray方法,传递数组变量array,完成数组按照指定格式打印

public class Demo02PrintArray {
public static void main(String[] args) {
//1.定义int数组array,并进行初始化
int[] array = {11,22,33,44,55};//array中存储的是: 数组在堆内存空间的地址值

//2.调用printArray方法,传递数组变量array,完成数组按照指定格式打印
printArray(array);

int[] array2 = {100,200,300,500,800,999,9999};
printArray(array2);
}

//打印int数组方法printArray的实现步骤
public static void printArray(int[] array) {
//1.打印"[",不换行
System.out.print("[");

//2.使用for循环遍历数组
for (int i = 0; i < array.length; i++) {
//2.1打印数组当前元素,不换行
System.out.print(array[i]);

//2.2如果步骤2.1中打印的元素不是最后一个元素,则需要打印", ",不换行
if (i != array.length - 1) {
System.out.print(", ");
}
}
//3.打印"]",可以换行也可以不换行
System.out.println("]");
}
}

方法练习求数组最大值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
需求:
设计一个方法用于获取int数组中元素的最大值

举例:
原数组: {11,22,33,44,55}
最大值: 55

三要素:
1.方法名称: getArrayMax
2.参数列表: int[] array
3.返回值类型: int

方法getArrayMax的实现步骤:
1.假设索引0对应的元素是最大的,保存到int变量max中
2.使用for循环依次获取后面的(从索引1开始)每个元素
2.1只要当前元素值 大于 max,说明max中的值,已经不是最大的了
2.2把当前元素值 赋值给 变量max
3.for循环结束后,返回max

main方法实现步骤:
1.定义int数组array,并初始化
2.调用getArrayMax方法,传递数组array,获取最大值,保存到int变量max中
3.打印最大值max

public class Demo03PrintArrayMax {
public static void main(String[] args) {
//1.定义int数组array,并初始化
int[] array = {100,200,300,800,500};

//2.调用getArrayMax方法,传递数组array,获取最大值,保存到int变量max中
int max = getArrayMax(array);//数组名array: 存储数组在堆内存中的地址值

//3.打印最大值max
System.out.println("数组元素最大值: "+max);
}

//设计一个方法用于获取一个int数组中元素的最大值
public static int getArrayMax(int[] array) {
//1.假设索引0对应的元素是最大的,保存到int变量max中
int max = array[0];

//2.使用for循环依次获取后面的(从索引1开始)每个元素
for (int i = 1; i < array.length; i++) {
//2.1只要当前元素值 大于 max,说明max中的值,已经不是最大的了
if (array[i] > max) {
//2.2把当前元素值 赋值给 变量max
max = array[i];
}
}
//3.for循环结束后,返回max
return max;
}
}

引用类型变量作为方法参数方法调用图解

image-20200518142225434