# JavaSE 基础 — Day05 笔记 > **日期**:2026-07-17 > **项目**:`c260717` > **作者**:WanJL --- ## 一、Java 方法(Method) ### 1. 方法概述 **方法(Method)** 在 Java 中称为方法,在 C/C++ 中称为函数。它们是给一段代码取名字,以后通过这个名字来调用这段代码。 > **作用**:让代码可以复用,分解整个程序的复杂度,方便测试和调试。 ### 2. 方法的四种声明方式 方法按照 **是否具有返回值** 和 **是否具有参数** 可以分为 4 种声明方式: #### 第 1 种:既没有参数、也没有返回值 ```java public static void 方法名() { // 方法体:封装的代码 } ``` - `public static`:修饰符(后续详细讲解) - `void`:当方法没有设置返回值类型时,需要使用 `void` 占位 - `方法名`:调用时使用方法名调用 - `()`:标识这是一个方法,并且可以定义参数 **示例**:计算用户输入的两个整数,累加后输出 ```java public static void add() { Scanner sc = new Scanner(System.in); System.out.println("请输入第1个数:"); int n1 = sc.nextInt(); System.out.println("请输入第2个数:"); int n2 = sc.nextInt(); int sum = n1 + n2; System.out.println("计算结果为:" + sum); } ``` 调用方式:`add();` #### 第 2 种:有方法参数,但是没有方法返回值 ```java public static void 方法名(参数类型1 参数名1, 参数类型2 参数名2, ..., 参数类型n 参数名n) { // 方法体 } ``` **示例**:计算两个整数相加并输出 ```java public static void add(int a, int b) { int sum = a + b; System.out.println(sum); } ``` 调用方式:`add(15, 7);` — 传入实际参数值 #### 第 3 种:有参数、有返回值 ```java public static 返回值类型 方法名(参数类型1 参数名1, ..., 参数类型n 参数名n) { // 方法体 return 返回值; // 返回值类型必须与方法声明一致 } ``` - 返回值类型可以是 **任何类型**(`int`、`double`、`boolean`、`int[]` 等) - 方法体中通过 `return` 语句返回结果 - 调用方可以**接收返回值**,也可以忽略(但一般都会接收使用) **示例**:传入 `int[]` 数组参数,返回数组中的最大值 ```java public static int getMaxElement(int[] arr) { int max = arr[0]; for (int i = 1; i < arr.length; i++) { if (arr[i] > max) { max = arr[i]; } } return max; } ``` 调用方式: ```java int[] scores = {80, 85, 77, 63, 84, 95, 86, 88}; int maxScore = getMaxElement(scores); // 接收返回值 System.out.println("最高分:" + maxScore); // 输出:最高分:95 ``` ### 3. main 方法调用示例 ```java public static void main(String[] args) { sub(15, 7); // 第2种:有参无返回值 printFor(); // 第1种:无参无返回值 getMax(7, 8, 9); // 第2种:有参无返回值 // 第3种:有参有返回值 — 接收返回值使用 int[] scores = {80, 85, 77, 63, 84, 95, 86, 88}; int maxScore = getMaxElement(scores); System.out.println("最高分:" + maxScore); } ``` ### 4. 方法练习(完整实现) > 以下为课堂练习,使用上述方法知识完成实现: #### 练习 1:两数相减 ```java /** * 声明一个计算2个整数相减的方法 * @param a 被减数 * @param b 减数 */ public static void sub(int a, int b) { System.out.println(a - b); } ``` 调用方式:`sub(15, 7);` // 输出 8 #### 练习 2:循环输出 1~100 ```java /** * 声明一个循环输出1~100的整数的方法 */ public static void printFor() { for (int i = 1; i <= 100; i++) { System.out.print(i + " "); } System.out.println(); } ``` #### 练习 3:三个数中取最大值 ```java /** * 声明一个获取三个变量中最大值的方法 * @param a * @param b * @param c */ public static void getMax(int a, int b, int c) { int max = (a > b ? a : b) > c ? (a > b ? a : b) : c; System.out.println(max); } ``` > **知识点**:使用**三元运算符**嵌套实现三个数的最大值比较。 #### main 方法调用 ```java public static void main(String[] args) { sub(15, 7); // 两数相减 printFor(); // 输出1~100 getMax(7, 8, 9); // 三个数取最大值 } ``` ### 5. 第 3 种方法练习(有参有返回值) > 以下练习对应**第 3 种方法声明方式** —— `public static 返回值类型 方法名(参数) { return 值; }` #### 练习 4:计算矩形周长 ```java /** * 定义一个计算矩形周长的方法 * @param a 长 * @param b 宽 * @return 矩形的周长 */ public static int recPerimeter(int a, int b) { return (a + b) * 2; } ``` 调用方式:`int p = recPerimeter(5, 3);` // 返回 16 #### 练习 5:计算矩形面积 ```java /** * 定义一个计算矩形面积的方法 * @param a 长 * @param b 宽 * @return 矩形的面积 */ public static int reaArea(int a, int b) { return a * b; } ``` #### 练习 6:计算圆形周长 ```java /** * 定义一个计算圆形周长的方法 * @param r 半径 * @return 圆形的周长 */ public static double rotundityPerimeter(int r) { return 3.14 * r * 2; } ``` #### 练习 7:计算圆形面积(方法调用方法) ```java /** * 定义一个计算圆形面积的方法 * @param r 半径 * @return 圆形的面积 */ public static double rotundityArea(int r) { // return 3.14 * r * r; return getPI() * r * r; // 调用了另一个方法 getPI() } ``` > **✨ 知识点:方法中调用另一个方法** > `rotundityArea` 内部调用了 `getPI()` 方法获取 π 值,体现了**方法的复用** —— 将获取 π 的逻辑抽取到独立方法中,多处调用。 #### 练习 8:判断闰年 ```java /** * 定义一个判断年份是否是闰年的方法 * @param year 年份 * @return true 表示闰年,false 表示平年 */ public static boolean isLeapYear(int year) { if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) { return true; } else { return false; } } ``` > **闰年规则**:能被 4 整除但不能被 100 整除,或者能被 400 整除。 --- ### 6. 第 4 种方法:无参数、有返回值 ```java public static 返回值类型 方法名() { // 方法体 return 返回值; } ``` **示例**:定义一个返回 π 值的方法 ```java /** * 定义一个返回 PI 的方法,没有参数,但是有返回值 * @return 圆周率 3.1415926 */ public static double getPI() { return 3.1415926; } ``` 调用方式: ```java double pi = getPI(); // 接收返回值 double area = getPI() * 5 * 5; // 直接在表达式中使用 ``` > **第 4 种方法特点**:不接收任何参数,但返回一个值。适合获取**固定常量**、**随机数**、**系统状态**等场景。 --- ### 7. 4 种方法声明方式速查 | 类型 | 声明格式 | 示例方法 | 适用场景 | |------|---------|---------|---------| | **无参无返回值** | `void 方法名()` | `add()`, `printFor()` | 打印菜单、输出固定内容 | | **有参无返回值** | `void 方法名(参数)` | `sub()`, `getMax()` | 根据传入数据执行操作并输出 | | **有参有返回值** | `类型 方法名(参数)` | `getMaxElement()`, `recPerimeter()`, `isLeapYear()` | 根据传入数据计算并返回结果 | | **无参有返回值** | `类型 方法名()` | `getPI()` | 获取固定常量或随机数 | --- ## 二、方法进阶 —— 数组作为方法参数(Demo02) ### 1. 概念 方法不仅可以接收 `int`、`double` 等基本类型参数,还可以接收**数组类型**的参数。 ```java public static void 方法名(数据类型[] 数组名) { // 方法体 } ``` ### 2. 示例:将排序算法封装为方法 ```java import java.util.Arrays; public class Demo02 { // 冒泡排序方法 public static void bubbleSort(int[] arr) { System.out.println("排序前:" + Arrays.toString(arr)); // 排序代码(略) System.out.println("排序后:" + Arrays.toString(arr)); } // 选择排序方法(占位) public static void selectionSort(int[] arr) {} // 插入排序方法(占位) public static void insertionSort(int[] arr) {} public static void main(String[] args) { int[] myScore = {80, 85, 77, 63, 84, 95, 86, 88}; bubbleSort(myScore); // 传入数组名 } } ``` ### 3. 关键点 | 项目 | 说明 | |------|------| | **参数声明** | `(int[] arr)` — 参数类型为 `int[]` 数组 | | **调用方式** | `bubbleSort(myScore);` — 直接传入数组名(不带方括号) | | **数组toString** | `Arrays.toString(arr)` — 将数组转换为可读的字符串形式 | | **封装意义** | 将排序算法封装到方法中,方便复用和测试 | ### 4. Arrays.toString() 工具方法 `Arrays.toString()` 是 `java.util.Arrays` 类提供的静态方法,用于将数组转换为格式化的字符串: ```java int[] arr = {80, 85, 77, 63, 84, 95, 86, 88}; System.out.println(Arrays.toString(arr)); // 输出:[80, 85, 77, 63, 84, 95, 86, 88] ``` --- ## 三、Random 随机数类(Demo03) ### 1. 概述 `java.util.Random` 是 Java 提供的**随机数生成器**类,功能比 `Math.random()` 更强大,可以生成各种类型的随机数。 ### 2. 创建 Random 对象 ```java // 方式一:无随机种子构造,每次运行生成的随机数都不同 Random ran = new Random(); // 方式二:有随机种子构造,相同种子会生成相同的随机数序列(一般用于测试) Random ran1 = new Random(42); ``` ### 3. 常用方法 ```java // 生成 int 类型的随机数(不指定范围) int n1 = ran.nextInt(); System.out.println(n1); // 可能是任何 int 值 // 生成指定范围的随机数(0 ~ 参数之间,包含 0,不包含参数) int n2 = ran.nextInt(100); System.out.println(n2); // 0 ~ 99 之间的随机数 ``` ### 4. 与 Math.random() 对比 | 对比项 | `Math.random()` | `Random` 类 | |--------|----------------|-------------| | 类型 | 静态方法 | 需要创建对象 | | 返回值 | `double` (0.0 ~ 1.0) | 多种类型 (`int`, `double`, `boolean` 等) | | 范围控制 | 需手动运算 `(int)(Math.random() * 范围)` | 直接 `nextInt(范围)` | | 适用场景 | 简单随机需求 | 复杂随机需求,或需要种子控制 | --- ## 四、Random + 方法综合练习(Demo04) > 结合 Random 类和方法的第 3、4 种声明方式,完成以下练习。 ### 课堂练习题 Demo04 中列出了 4 道练习,目前实现了 `getRandomColor()`: ```java import java.util.Arrays; import java.util.Random; public class Demo04 { // 生成随机颜色 RGB — 返回 int[] 数组 public static int[] getRandomColor() { int[] color = new int[3]; Random ran = new Random(); color[0] = ran.nextInt(256); // R: 0~255 color[1] = ran.nextInt(256); // G: 0~255 color[2] = ran.nextInt(256); // B: 0~255 return color; } public static void main(String[] args) { int[] color = getRandomColor(); System.out.println(Arrays.toString(color)); } } ``` ### 练习列表 | 练习 | 方法名 | 类型 | 说明 | |------|--------|------|------| | 1 | `getVerificationCode()` | 无参有返回值 | 生成 100000~999999 的 6 位验证码 | | 2 | `getLuckyNumber()` | 无参有返回值 | 生成 1~100 的幸运数字 | | 3 | `diceRoll()` | 无参有返回值 | 模拟抛骰子,返回 1~6 | | 4 | `getRandomColor()` | 无参有返回值(返回数组) | 返回 3 个 RGB 分量的 int[] 数组(已实现) | > **提示**:`ran.nextInt(范围)` 生成的是 0 ~ (范围-1) 的随机数,如需从其他值开始,可以加上偏移量。 --- ## 五、在线 OJ 编码模板(Main.java) > 这是一个解决在线 OJ 平台提交代码时中文乱码问题的模板。 ```java import java.io.PrintStream; import java.io.UnsupportedEncodingException; public class Main { public static void main(String[] args) throws UnsupportedEncodingException { // 设置系统输出的字符编码为 UTF-8,解决中文乱码 System.setOut(new PrintStream(System.out, true, "UTF-8")); // 后面写代码... } } ``` > **原因**:本地 IDEA 使用 UTF-8 编码,但部分在线 OJ 平台使用 GBK 解码,导致中文乱码。 --- ## 六、课后作业 —— 三种排序算法复习 > 本日作业巩固了 7 月 16 日学习的三种排序算法。 ### 作业 1:冒泡排序(HomeWork01) ```java // 冒泡排序 — 优化版本(带提前结束标记) int[] arr = {29, 10, 14, 37, 13, 33, 48, 22}; // arr.length - 1 是比较的轮数 for (int i = 0; i < arr.length - 1; i++) { boolean b = false; // 标记是否出现提前排完序的情况 for (int j = 0; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j + 1]) { // 通过加减法交换两数(不使用临时变量) arr[j] = arr[j] + arr[j + 1]; arr[j + 1] = arr[j] - arr[j + 1]; arr[j] = arr[j] - arr[j + 1]; b = true; // 标记本轮有交换,说明还没排完序 } } // 如果 b == false,说明已经排序完成,提前跳出循环 if (!b) { break; } } ``` #### 冒泡排序核心思想 | 项目 | 说明 | |------|------| | 排序方式 | 比较相邻元素的大小,较大的交换位置 | | 最多轮数 | 长度 - 1 轮 | | 每轮比较次数 | 逐次减少,最长 - 1 次 | | 优化手段 | 通过 `boolean` 标记判断是否提前完成排序 | | 交换技巧 | 使用加减法交换两数,无需临时变量 | ### 作业 2:选择排序 — 降序(HomeWork02) > 选择排序:选出来最小的元素,和第 1 个元素进行交换。每一轮外层循环只交换 1 次。 ```java // 选择排序(降序)— 选最大的 int[] arr = {56, 23, 89, 12, 45, 67, 34, 78}; // 外层循环,i 既是已排序区间的末尾边界,也是当前要确定的位置 for (int i = 0; i < arr.length - 1; i++) { // 假设当前未排序区间的第 1 个元素是最大的 int maxIndex = i; // 通过一轮循环,选出最大元素的索引值 for (int j = i + 1; j < arr.length; j++) { if (arr[j] > arr[maxIndex]) { maxIndex = j; } } // 如果最大值不在 i 的位置,则交换 if (maxIndex != i) { arr[maxIndex] = arr[maxIndex] + arr[i]; arr[i] = arr[maxIndex] - arr[i]; arr[maxIndex] = arr[maxIndex] - arr[i]; } } ``` #### 选择排序核心思想 | 项目 | 说明 | |------|------| | 排序方式 | 每轮选出最大(或最小)元素,与当前位置交换 | | 交换次数 | 每轮最多交换 1 次 | | 降序实现 | 每轮选出最大值放到前面 | | 交换条件 | 仅当 `maxIndex != i` 时才交换 | ### 作业 3:插入排序 — 升序(HomeWork03) > 把一个数组分为两部分:已排序部分和未排序部分。从未排序部分取出第 1 个元素,与已排序部分从最后一个元素开始比较,直到找到比这个元素小的元素,放到它后面。 ```java // 插入排序(升序) int[] studentScores = {88, 72, 93, 65, 81, 97, 78, 85}; // 从第 2 个元素开始(假设第 1 个元素是已排序部分) for (int i = 1; i < studentScores.length; i++) { // 当前要插入的元素 int current = studentScores[i]; // 已排序部分的最后一个元素的索引 int j = i - 1; // 从后往前扫描已排序部分,寻找插入位置 while (j >= 0 && studentScores[j] > current) { studentScores[j + 1] = studentScores[j]; // 往后移动一位 j--; } // j + 1 就是 current 应该插入的位置 studentScores[j + 1] = current; } ``` #### 插入排序核心思想 | 项目 | 说明 | |------|------| | 排序方式 | 将数组分为已排序和未排序两部分 | | 起始状态 | `studentScores[0]` 为已排序部分 | | 插入方式 | 从后往前扫描已排序部分,找到合适位置插入 | | 移动方式 | 比当前元素大的元素均向后移动一位 | --- ## 七、课后作业 —— Scanner 学生信息采集系统(HomeWork04) > 使用 `Scanner` 键盘输入,采集学生信息并计算 BMI 指数。 ### 信息采集表 | 信息项 | 数据类型 | 提示语 | |--------|----------|--------| | 姓名 | `String` | `请输入您的姓名:` | | 学号 | `String` | `请输入您的学号:` | | 年龄 | `int` | `请输入您的年龄:` | | 性别 | `String` | `请输入您的性别(男/女):` | | 身高(米) | `double` | `请输入您的身高(米):` | | 体重(公斤) | `double` | `请输入您的体重(公斤):` | | 是否在校 | `boolean` | `请输入您是否在校(true/false):` | ### 开发中常用的类型选择 | 场景 | 推荐类型 | 说明 | |------|----------|------| | 整数 | `int` | 大部分整数使用 int | | 字符、数字、符号 | `String` | 其余所有情况基本都用 String | | 小数 | `double` | 所有小数都使用 double | | 二值选择 | `boolean` | 可能出现 2 个值的,一般用于判断 | ### 完整代码示例 ```java public static void main(String[] args) { // 1、创建 Scanner 对象 Scanner sc = new Scanner(System.in); System.out.println("请输入您的姓名:"); String name = sc.next(); System.out.println("请输入您的学号:"); String id = sc.next(); System.out.println("请输入您的年龄:"); int age = sc.nextInt(); System.out.println("请输入您的性别(男/女):"); String gender = sc.next(); System.out.println("请输入您的身高(米):"); double height = sc.nextDouble(); System.out.println("请输入您的体重(公斤):"); double weight = sc.nextDouble(); System.out.println("请输入您是否在校(true/false):"); boolean isStudent = sc.nextBoolean(); System.out.println("======== 学生信息卡 ========"); System.out.println("姓名:" + name); System.out.println("学号:" + id); System.out.println("年龄:" + age); System.out.println("性别:" + gender); System.out.println("身高:" + height); System.out.println("体重:" + weight); System.out.println("在校学生:" + isStudent); // BMI = 体重 ÷ (身高 × 身高) double bmi = weight / (height * height); System.out.printf("BMI:%.2f", bmi); System.out.println(); // 体型判定 int b; if (bmi < 18.5) { b = 1; } else if (bmi >= 18.5 && bmi < 24) { b = 2; } else if (bmi >= 24 && bmi < 28) { b = 3; } else { b = 4; } System.out.print("体型判定:"); switch (b) { case 1 -> System.out.println("偏瘦"); case 2 -> System.out.println("正常"); case 3 -> System.out.println("偏胖"); default -> System.out.println("肥胖"); } System.out.println("============================"); } ``` ### BMI 判定标准 | BMI 范围 | 体型判定 | |----------|----------| | BMI < 18.5 | 偏瘦 | | 18.5 ≤ BMI < 24 | 正常 | | 24 ≤ BMI < 28 | 偏胖 | | BMI ≥ 28 | 肥胖 | ### 知识点回顾 - **Scanner 基础方法**: - `sc.next()` — 读取字符串 - `sc.nextInt()` — 读取整数 - `sc.nextDouble()` — 读取小数 - `sc.nextBoolean()` — 读取布尔值 - **printf 格式化输出**:`System.out.printf("BMI:%.2f", bmi);` — 保留两位小数 - **switch 箭头语法**:`case 1 -> System.out.println("偏瘦");` — Java 14+ 新特性 --- ## 八、本日总结 | 知识点 | 主要内容 | |--------|----------| | **Java 方法 4 种声明方式** | 无参无返回值、有参无返回值、有参有返回值、无参有返回值 | | **第 1 种:无参无返回值** | `void 方法名()` — `add()`, `printFor()` | | **第 2 种:有参无返回值** | `void 方法名(参数)` — `sub()`, `getMax()` | | **第 3 种:有参有返回值** | `类型 方法名(参数)` — `getMaxElement()`, `recPerimeter()`, `reaArea()`, `rotundityPerimeter()`, `rotundityArea()`, `isLeapYear()` | | **第 4 种:无参有返回值** | `类型 方法名()` — `getPI()` | | **方法中调用方法** | `rotundityArea()` 内部调用 `getPI()` — 体现代码复用 | | **数组作为方法参数** | `bubbleSort(int[] arr)` 将数组传入方法、`Arrays.toString()` 打印数组 | | **Random 随机数类** | `Random` 对象创建、`nextInt()` 无范围 / `nextInt(范围)` 有范围随机数 | | **Random + 方法综合** | `getRandomColor()` 返回 `int[]` 数组、4 道课堂练习题 | | **在线 OJ 编码模板** | `System.setOut()` 解决 UTF-8/GBK 中文乱码问题 | | **冒泡排序** | 相邻比较、交换、提前结束优化 | | **选择排序** | 每轮选最大值、降序排列 | | **插入排序** | 已排序/未排序分区、从后往前插入 | | **Scanner 综合应用** | 学生信息采集、BMI 计算与体型判定 | | **switch 箭头语法** | `case ->` 新式写法 | | **printf 格式化** | `%.2f` 保留两位小数 |