03–04. java学习 – 流程控制语句、数组、方法
一、流程控制语句
1. 判断语句
1.1. if语句 – 区间判断
1. if语句:
- 若条件判断为true,则执行代码块的内容
** if语句的格式: **
if(条件表达式){
// 满足条件表达式的代码
}
需要注意: 条件表达式的结果必须boolean值。
换言之,结果为boolean的都可以放在这里。
// 例子:
int a = 10;
int b = 20;
if(a < b){
System.out.println(a);
} // 10
2. if-else语句:
- 若条件判断为true,则执行if代码块的内容
- 若条件判断为false,则执行else代码块的内容
** if-else的语句格式:**
if(条件表达式){
// 满足条件表达式的时候,执行的语句
}else{
// 不满足条件表达式执行的语句
}
// 例子:
int a = 10;
int b = 5;
if(a < b){
System.out.println(a);
}else{
System.out.println(b);
} // 5
3. if-else if …-else语句:
- 各个分支语句的条件判断区间一定要有序
- 从上到下依次判断条件表达式是否为true,当某一个条件表达式为true后,剩下的分支语句都不会执行
** if-else if ...-else语句格式: **
if(条件表达式1){
执行语句1;
}else if(条件表达式2){
执行语句2;
}else if(条件表达式3){
执行语句3;
} ... ...
else{
以上条件都不满足,执行的语句
}
// 例子:根据考试分数,判断学生等级
// 90 - 100 优秀
// 80 - 90 良好
// 60 - 80 及格
// 小于60 不及格
public class IfElseIfDemo1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个分数:");
int score = scanner.nextInt();
if(score >= 90){
System.out.println("等级:优秀");
}else if(score >= 80){
System.out.println("等级:良好");
} else if(score >= 60){
System.out.println("等级:及格");
}else{
System.out.println("等级:不及格");
}
}
}
1.2. switch语句 – 等值判断
1. switch语句
- 计算switch语句中表达式的值
- 将表达式的值和case分支语句中的常量值进行比较
- 如果相同就执行对应case分支语句里面的内容
- 遇到break之后,就跳出分支语句,结束整个switch语句
- 如果所有的case分支语句都不满足,就执行default语句里面的内容
** switch语句格式:**
switch(表达式){
case 常量值1:
语句体1;
break;
case 常量值2:
语句体2;
break;
... ...
default:
执行default语句分支;
break;
}
// 例子:根据用户输入的月份,判断属于哪个季度
public class SwitchDemo1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入月份:");
int month = scanner.nextInt();
switch (month){
case 1:
System.out.println("这是第一季度");
break;
case 2:
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;
case 12:
System.out.println("这是第四季度");
break;
default:
System.out.println("月份输入有误");
break;
}
}
}
以上代码的问题是:存在大量的冗余部分
我们可以利用switch语句的击穿特性来进行简化
原理:一旦case匹配,就会顺序执行后面的程序代码,而不管后面的case是否匹配,直到遇见break
public class SwitchDemo2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入月份:");
int month = scanner.nextInt();
switch (month){
case 1:
case 2:
case 3:
System.out.println("这是第一季度");
break;
case 4:
case 5:
case 6:
System.out.println("这是第二季度");
break;
case 7:
case 8:
case 9:
System.out.println("这是第三季度");
break;
case 10:
case 11:
case 12:
System.out.println("这是第四季度");
break;
default:
System.out.println("月份输入有误");
break;
}
}
}
2. 循环语句
2.1. for循环
** for循环格式:**
for(初始化表达式①;布尔表达式②;表达式④){
// 满足循环条件执行的代码③
}
for循环的执行流程:
- 执行顺序: ①②③④ --> ②③④ --> ②③④ … ②
- 表达式①主要负责变量的初始化
- 表达式②负责判断是否满足某个循环条件,满足就执行循环体,不满足则跳出循环
- 循环体,满足循环条件执行的代码
- 表达式④,循环体执行完成之后,相关的变量要进行动态的变化
// 例子:输出1-100之间所有偶数之和
public class ForDemo3 {
public static void main(String[] args) {
int sum = 0; // 接收所有偶数之和
for (int i = 1; i <= 100 ; i++) {
//满足偶数条件
if(i % 2 == 0){
sum += i;
}
}
System.out.println("1-100之间的所有偶数之和是:" + sum);
}
} // 2550
2.2. while循环
while循环执行的顺序类似于for循环
** while循环格式:**
初始化表达式①
while(布尔表达式②){
循环体③;
表达式④
}
while循环的执行流程:
- 执行顺序: ①②③④ --> ②③④ --> ②③④ … ②
- 表达式①主要负责变量的初始化
- 表达式②负责判断是否满足某个循环条件,满足就执行循环体,不满足则跳出循环
- 循环体,满足循环条件执行的代码
- 表达式④,循环体执行完成之后,相关的变量要进行动态的变化
// 例子:求1-100之间的数字之和
public class WhileDemo2 {
public static void main(String[] args) {
int sum = 0;
int i = 1;
while(i<=100){
sum+=i;
i++;
}
System.out.println("1-100之间的数字之和是:" + sum);
}
} // 5050
2.3. do-while循环
** do-while循环格式:**
初始化表达式①
do{
循环体③
表达式④
}while(布尔表达式②);
do-while循环的执行流程:
- 执行顺序: ①③④ --> ②③④ --> ②③④ … -->②不满足,就跳出循环
- ①相关变量的初始化
- ② 判断是否满足循环条件,满足执行循环体,不满足则跳出循环
- ③ 满足循环条件执行的循环体
- ④ 相关变量的动态变化
- 注意:不管循环条件满足不满足,循环体都会无条件的执行1次
// 例子:使用do-while输出10次hello world
public class DoWhile {
public static void main(String[] args) {
int i = 1;
do{
System.out.println("hello world....");
i++;
}while(i<=10);
}
}
3.break和continue关键字
相同点:都可以在循环体内使用且都可以用来跳出(结束)循环
不同点:
- break关键字:
- 单层循环:结束整个循环,循环剩下的语句不再执行,去执行循环体外的代码
- 多层循环:只结束break所在的循环,更外层循环不会跳出
- continue关键字
- 跳过循环体剩余的循环语句,结束本次循环且强制进行下一次循环
// 例子:找到一定范围内所有的质数
public static void getPrimeNumber(int num){
for(int i = 2;i <= num;i++){
boolean count = true;
for(int j = 2;j <= Math.sqrt(i);j++){
if(i % j == 0){
count = false;
break;
}
}
if(count){
System.out.println(i + "是质数");
}
count = true;
}
}
二、数组
1. 数组是什么
数组是用来批量保存数据的容器
特点:
- 存在数据类型
- 有序
- 长度一旦声明就不可更改
2. 一维数组定义
数组类型[] 数组名 = new 数组类型[数组长度];
数组类型[] 数组名 = new 数组类型[] {元素1, 元素2, 元素3,…};
数组类型[] 数组名 = {元素1, 元素2, 元素3,…};
new 是用来创建对象的一个关键字
// 例子:
// 方式1
int[] arr = new int[5];
// 方式2
int[] arr1 = new int[]{10,22,34,56,98,33};
// 方式3
int[] arr2 = {10,23,45,67,89,100};
3. 一维数组访问
1. 获取特定元素的格式:
- 格式: 数组名称[索引]
// 例子
int[] arr2 = {10,23,45,67,89,100};
System.out.println(arr2[3]); // 67
2. 获取数组长度的格式:
- 数组名称.length
- 数组最大的索引是数组的长度-1
// 例子
int[] arr2 = {10,23,45,67,89,100};
System.out.println("arr2数组的长度:" + arr2.length); // 6
4. 数组的内存
首先我们要明确两块内存的用途。
- 栈内存:用来存放局部变量,方法的执行是在栈内存中执行
- 堆内存:用来存储对象,凡是使用new关键字创建出来的对象都放在堆内存中
- 因此,数组的内容储存在堆内存中,而栈内存储存的是堆内存的地址
// 例子
public class ArrayDemo2 {
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr); // 输出的是数组对象的内存地址
}
}
再看一个例子:
public class ArrayDemo2 {
public static void main(String[] args) {
int[] arr = new int[3];
// 给数组的元素赋值
arr[0] = 10;
arr[1] = 12;
arr[2] = 15;
// 将arr这个数组对象的内存地址赋予给arr2这个变量。
// 此时arr和arr2这两个变量指向了同一个数组对象
int[] arr2 = arr;
arr2[2] = 200;
System.out.println(arr[2]); // 200
}
}
数组的默认值:
- 整形数组默认值:0
- 浮点型数组默认值:0.0
- 字符型数组默认值:0(或理解为‘\u0000’)
- 布尔型数组默认值:false(不知道跟程序中用0来表示false有没有关系)
引用数据类型默认值:null
5. 数组可能出现的问题
5.1. 数组下标越界
数组中添加的元素,超过了数组的大小
public class ArrayDemo3 {
public static void main(String[] args) {
int[] arr = new int[3];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4; // 下标越界
System.out.println(arr);
}
}
5.2. 空指针异常
定义了数组,但是不指向堆内存中的任何对象
public class ArrayDemo4 {
public static void main(String[] args) {
int[] arr = new int[3];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr = null; // 不指向堆内存中的任何对象
System.out.println(arr[2]);
}
}
6. 获取数组中元素的方法
6.1. for循环遍历
// 例子
int[] arr = {1,2,3,4};
for(int i = 0;i < arr.length;i++){
System.out.print(arr[i] + "\t");
} // 1 2 3 4
6.2. 增强for循环
增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的
**语法格式**
for(元素类型 元素名(自定义即可):集合名或数组名){
访问元素;
}
其中,元素类型要与数组或集合中存放的数据的类型一致。
// 例子
int[] arr = {1,2,3,4,5};
for(int i : arr){
System.out.print(i + "\t");
} // 1 2 3 4 5
三、方法
**定义方法的格式:**
修饰符 返回值类型 方法名(参数列表){
功能代码块
... ...
return 结果; // 如果返回值为void 是可以不写return语句的
}
1. 无参无返回值定义
**无参无返回值方法: **
public static void 方法名(){
//功能代码块
}
说明:
- 修饰符: 暂时修饰符的固定写法:public (static)
- 返回值类型:方法执行完成之后,需要给调用者返回一个数据结果。
- void: 不返回数据, 有返回值就写具体的数据类型
- 方法名: 见名知意
- return: 标识方法的结束。还有就是将方法的数据结果返回给调用者。如果方法的返回值是void,return关键字可以不用写
// 例子:
public class MethodDemo1 {
public static void main(String[] args) {
//在当前方法所属类的内部进行调用,直接通过方法名调用即可
hello();
}
// 定义一个无参数无返回值的方法
public static void hello(){
System.out.println("这是一个无参数无返回值的方法");
}
}
2.有参无返回值定义
**有参无返回值方法: **
public static void 方法名(数据类型 参数1,......){
//功能代码块
}
// 例子:
public class MethodDemo3 {
public static void main(String[] args) {
//调用一个带参数的方法,就必须传递参数(实际参数)
juxing(2,5);
}
public static void juxing(int width,int length){
int area = width * length;
System.out.println("矩形的面积是:" + area);
}
}
3. 有返回值方法定义
**有返回值方法: **
public static 数据类型 方法名称(参数列表){
方法逻辑代码
return 返回结果;
}
需要注意的是: 返回值的数据结果必须和声明的返回值的数据类型保持一致。
在调用带返回值的方法的时候,也需要使用变量来接收方法的返回结果。
// 例子:
public class MethodDemo3 {
public static void main(String[] args) {
// 带返回值的方法,我们需要使用一个变量来接收方法的数据结果
double area = getArea(5);
System.out.println("原型的面积是:" + area);
}
//定义一个带返回值的方法,计算圆形的面积
public static double getArea(int r){
double area = 3.14*r*r;
return area; // return的数据结果必须要和返回值声明的数据结果一致。
}
}
4. 自定义类型 – 对某种事物进行的抽象概括
4.1. 格式
**类的定义格式:**
访问修饰符 class 类名{
//定义属性(成员变量,位于方法的外部,类的内部)
数据类型 变量名称;
... ...
//定义方法 (成员方法)
}
访问修饰符:
- public(公共:对所有类可见)
- private(私有:只能在类内部访问)
- protected(保护:可通过子类对象、同一包内的对象访问)
// 例子:创建一个学生类
public class Student {
public String name;
public int age;
public String studentClass;
public String address;
public double score;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", studentClass='" + studentClass + '\'' +
", address='" + address + '\'' +
", score=" + score +
'}';
}
}
4.2. 类的使用
类的使用方法:
- 创建类对象:类名 对象名 = new 类名();
- 给对象赋值:对象名.成员变量 = 值;
- 获取属性值:对象名.属性名;
- 调用方法:对象名.方法名();
// 例子:定义一个Student类型的数组,Student有name score age。
// 找出最高分的学生姓名和分数,及最低分的学生姓名和分数
public class StudentTestDemo {
public static void main(String[] args) {
Student student01 = new Student();
Student student02 = new Student();
Student student03 = new Student();
Student[] stuArray = {student01,student02,student03};
student01.name = "L";
student02.name = "A";
student03.name = "S";
for(int i = 0 ;i < stuArray.length;i++){
stuArray[i].age = random.nextInt(10) + 1;
stuArray[i].score = random.nextDouble() * 100;
}
System.out.println("Student数组为:");
for (Student s : stuArray){
System.out.println(s);
}
getStudentScore(stuArray);
}
public static void getStudentScore(Student[] students){
double max = students[0].score;
double min = students[0].score;
int maxId = 0;
int minId = 0;
for (int i = 0;i < students.length;i++){
if(students[i].score < min){
min = students[i].score;
minId = i;
}
if (students[i].score > max){
max = students[i].score;
maxId = i;
}
}
System.out.println("最高分学生姓名为:" + students[maxId].name + ",分数是:" + max);
System.out.println("最低分学生姓名为:" + students[minId].name + ",分数是:" + min);
}
}
四、其他
补充IDEA快捷键:
- 快速生成toString:Alt+Insert
- 生成多个光标一次修改多个元素:Shift+Alt+要修改的地方