|
@@ -537,7 +537,136 @@ for (int i = 1; i < arr.length; i++) {
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
-## 七、课堂练习详解
|
|
|
|
|
|
|
+## 七、Scanner 键盘输入
|
|
|
|
|
+
|
|
|
|
|
+### 1. Scanner 概述
|
|
|
|
|
+
|
|
|
|
|
+`java.util.Scanner` 是 Java 提供的**键盘输入工具类**,可以读取用户在控制台中输入的数据。
|
|
|
|
|
+
|
|
|
|
|
+#### 使用步骤
|
|
|
|
|
+
|
|
|
|
|
+| 步骤 | 说明 | 代码 |
|
|
|
|
|
+|------|------|------|
|
|
|
|
|
+| **① 导包** | 引入 Scanner 类(IDEA 可自动导包) | `import java.util.Scanner;` |
|
|
|
|
|
+| **② 创建对象** | 创建 Scanner 对象,绑定到系统输入 | `Scanner sc = new Scanner(System.in);` |
|
|
|
|
|
+| **③ 读取数据** | 调用对应的方法读取不同类型的数据 | `sc.nextInt()`、`sc.next()` 等 |
|
|
|
|
|
+| **④ 关闭资源** | 关闭 Scanner 释放资源 | `sc.close();` |
|
|
|
|
|
+
|
|
|
|
|
+> `System.in` 属于**系统标准输入流**,Scanner 通过它来读取用户在控制台的输入。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### 2. 常用方法
|
|
|
|
|
+
|
|
|
|
|
+| 方法 | 读取类型 | 示例 |
|
|
|
|
|
+|------|---------|------|
|
|
|
|
|
+| `sc.nextByte()` | 整数 byte | `byte b = sc.nextByte();` |
|
|
|
|
|
+| `sc.nextShort()` | 整数 short | `short s = sc.nextShort();` |
|
|
|
|
|
+| `sc.nextInt()` | 整数 int | `int i = sc.nextInt();` |
|
|
|
|
|
+| `sc.nextLong()` | 整数 long | `long l = sc.nextLong();` |
|
|
|
|
|
+| `sc.nextFloat()` | 小数 float | `float f = sc.nextFloat();` |
|
|
|
|
|
+| `sc.nextDouble()` | 小数 double | `double d = sc.nextDouble();` |
|
|
|
|
|
+| `sc.next()` | **单个字符串**(以空格/换行符为结束符) | `String s = sc.next();` |
|
|
|
|
|
+| `sc.nextLine()` | **整行字符串**(以换行符为结束符) | `String line = sc.nextLine();` |
|
|
|
|
|
+| `sc.nextBoolean()` | 布尔值 boolean | `boolean b = sc.nextBoolean();` |
|
|
|
|
|
+| `sc.next().charAt(0)` | 字符 char | `char c = sc.next().charAt(0);` |
|
|
|
|
|
+
|
|
|
|
|
+#### 基本示例
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+Scanner sc = new Scanner(System.in);
|
|
|
|
|
+
|
|
|
|
|
+// 读取整数
|
|
|
|
|
+int a = sc.nextInt();
|
|
|
|
|
+int b = sc.nextInt();
|
|
|
|
|
+System.out.println("a + b = " + (a + b));
|
|
|
|
|
+
|
|
|
|
|
+// 读取字符串
|
|
|
|
|
+String s = sc.next();
|
|
|
|
|
+System.out.println(s);
|
|
|
|
|
+
|
|
|
|
|
+sc.close();
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 综合练习 — 用户信息采集
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+Scanner sc = new Scanner(System.in);
|
|
|
|
|
+
|
|
|
|
|
+System.out.println("请输入您的姓名:");
|
|
|
|
|
+String name = sc.next();
|
|
|
|
|
+
|
|
|
|
|
+System.out.println("请输入您的年龄:");
|
|
|
|
|
+int age = sc.nextInt();
|
|
|
|
|
+
|
|
|
|
|
+System.out.println("请输入您的身高(米):");
|
|
|
|
|
+double height = sc.nextDouble();
|
|
|
|
|
+
|
|
|
|
|
+System.out.println("您是否是在校学生(true/false):");
|
|
|
|
|
+boolean isStudent = sc.nextBoolean();
|
|
|
|
|
+
|
|
|
|
|
+System.out.println("\n========用户信息========");
|
|
|
|
|
+System.out.println("姓名:" + name);
|
|
|
|
|
+System.out.println("年龄:" + age);
|
|
|
|
|
+System.out.println("身高:" + height);
|
|
|
|
|
+System.out.println("在校学生:" + isStudent);
|
|
|
|
|
+
|
|
|
|
|
+sc.close();
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### 3. Scanner 的常见陷阱
|
|
|
|
|
+
|
|
|
|
|
+#### 陷阱:`nextInt()` 后面使用 `nextLine()` 的问题
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+int a = sc.nextInt();
|
|
|
|
|
+String s = sc.nextLine();
|
|
|
|
|
+
|
|
|
|
|
+System.out.println(a); // 输出数字
|
|
|
|
|
+System.out.println(s); // ❌ 直接输出空字符串,没有等待输入!
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**问题原因**:
|
|
|
|
|
+- `nextInt()` 读取完数字后,**换行符 `\n` 仍停留在输入缓冲区**中
|
|
|
|
|
+- `nextLine()` 以换行符为结束符,遇到缓冲区中的换行符就**直接结束了**
|
|
|
|
|
+- 所以 `s` 读取到的是一个空字符串,程序不会等待用户输入
|
|
|
|
|
+
|
|
|
|
|
+**解决方案**:在 `nextInt()` 之后调用一次 `nextLine()` **吃掉多余的换行符**。
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+int a = sc.nextInt();
|
|
|
|
|
+sc.nextLine(); // ✅ 吃掉缓冲区中的换行符
|
|
|
|
|
+String s = sc.nextLine(); // ✅ 正常读取整行字符串
|
|
|
|
|
+
|
|
|
|
|
+System.out.println(a);
|
|
|
|
|
+System.out.println(s);
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+> ⚠️ **注意事项**:
|
|
|
|
|
+> - 在控制台中使用键盘输入的值,**必须符合 Scanner 接收的类型**,否则会抛出异常导致程序结束
|
|
|
|
|
+> - 例如用 `nextInt()` 读取时输入了字母,会抛出 `InputMismatchException`
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### 4. `next()` vs `nextLine()` 区别
|
|
|
|
|
+
|
|
|
|
|
+| 特性 | `next()` | `nextLine()` |
|
|
|
|
|
+|------|----------|-------------|
|
|
|
|
|
+| **结束符** | 空格、Tab、换行符 | **仅换行符** |
|
|
|
|
|
+| **能否读取空格** | ❌ 不能(遇到空格停止) | ✅ 能(读取整行) |
|
|
|
|
|
+| **典型场景** | 读取单个单词 | 读取包含空格的句子 |
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+// 输入:Hello World
|
|
|
|
|
+System.out.println(sc.next()); // 输出:Hello(遇到空格停止)
|
|
|
|
|
+System.out.println(sc.nextLine()); // 输出:World(读取剩余部分)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 八、课堂练习详解
|
|
|
|
|
|
|
|
### 练习 01:首尾对称交换数组元素
|
|
### 练习 01:首尾对称交换数组元素
|
|
|
|
|
|
|
@@ -686,7 +815,7 @@ for (int i = 0; i < newArr.length; i++) {
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
-## 八、课后作业讲解(7月15日作业)
|
|
|
|
|
|
|
+## 九、课后作业讲解(7月15日作业)
|
|
|
|
|
|
|
|
### 作业 07:数组元素求和
|
|
### 作业 07:数组元素求和
|
|
|
|
|
|
|
@@ -774,7 +903,7 @@ System.out.println("奇数个数:" + count + ",偶数个数:" + (arr.lengt
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
-## 九、随堂练习要点
|
|
|
|
|
|
|
+## 十、随堂练习要点
|
|
|
|
|
|
|
|
1. **多维数组本质**:数组的数组,二维数组的元素是一维数组的引用地址
|
|
1. **多维数组本质**:数组的数组,二维数组的元素是一维数组的引用地址
|
|
|
2. **二维数组定义**:`int[][] arr = new int[3][2];`(3 行 2 列)
|
|
2. **二维数组定义**:`int[][] arr = new int[3][2];`(3 行 2 列)
|
|
@@ -805,21 +934,28 @@ System.out.println("奇数个数:" + count + ",偶数个数:" + (arr.lengt
|
|
|
27. **插入排序-内层 while**:从后往前扫描已排序部分,比 current 大的元素逐一后移
|
|
27. **插入排序-内层 while**:从后往前扫描已排序部分,比 current 大的元素逐一后移
|
|
|
28. **插入排序-实用性**:三种基础排序中最实用,数据基本有序时效率可达 O(n)
|
|
28. **插入排序-实用性**:三种基础排序中最实用,数据基本有序时效率可达 O(n)
|
|
|
29. **三种排序实用性排序**:插入排序 > 选择排序 > 冒泡排序
|
|
29. **三种排序实用性排序**:插入排序 > 选择排序 > 冒泡排序
|
|
|
-30. **变量交换-临时变量法**:`tmp = a; a = b; b = tmp;`
|
|
|
|
|
-31. **变量交换-加减法**:`a = a + b; b = a - b; a = a - b;`
|
|
|
|
|
-32. **首尾交换**:利用对称性,第 i 位与第 length-1-i 位交换
|
|
|
|
|
-33. **循环右移**:从后往前逐个移动,保存最后一个元素放到开头
|
|
|
|
|
-34. **取模优化**:`k = k % arr.length` 解决 k 大于数组长度的问题
|
|
|
|
|
-35. **数组去重思路**:统计不重复个数 → 创建新数组 → 填充不重复元素
|
|
|
|
|
-36. **布尔标记法**:使用 `boolean` 变量标记元素是否重复
|
|
|
|
|
-37. **打擂法找最大值**:假设第一个是最大值,遇到更大的就更新
|
|
|
|
|
-38. **数组求和**:遍历数组,累加每个元素
|
|
|
|
|
-39. **倒序输出**:从 `length-1` 到 `0` 递减遍历
|
|
|
|
|
-40. **奇偶判断**:`n % 2 == 0` 偶,`n % 2 != 0` 奇
|
|
|
|
|
|
|
+30. **Scanner 键盘输入**:`java.util.Scanner` 类读取控制台输入
|
|
|
|
|
+31. **Scanner 使用步骤**:导包 → 创建对象 → 调用方法读取 → 关闭资源
|
|
|
|
|
+32. **Scanner 常用方法**:`nextInt()`、`nextDouble()`、`next()`、`nextLine()`、`nextBoolean()` 等
|
|
|
|
|
+33. **`next()` vs `nextLine()`**:`next()` 以空格/换行结束,`nextLine()` 仅以换行结束
|
|
|
|
|
+34. **Scanner 陷阱**:`nextInt()` 后使用 `nextLine()` 会读取到空字符串
|
|
|
|
|
+35. **Scanner 陷阱解决**:在 `nextInt()` 后调用一次 `nextLine()` 吃掉换行符
|
|
|
|
|
+36. **Scanner 类型匹配**:输入的值必须符合 Scanner 接收的类型,否则抛出 `InputMismatchException`
|
|
|
|
|
+37. **变量交换-临时变量法**:`tmp = a; a = b; b = tmp;`
|
|
|
|
|
+38. **变量交换-加减法**:`a = a + b; b = a - b; a = a - b;`
|
|
|
|
|
+39. **首尾交换**:利用对称性,第 i 位与第 length-1-i 位交换
|
|
|
|
|
+40. **循环右移**:从后往前逐个移动,保存最后一个元素放到开头
|
|
|
|
|
+41. **取模优化**:`k = k % arr.length` 解决 k 大于数组长度的问题
|
|
|
|
|
+42. **数组去重思路**:统计不重复个数 → 创建新数组 → 填充不重复元素
|
|
|
|
|
+43. **布尔标记法**:使用 `boolean` 变量标记元素是否重复
|
|
|
|
|
+44. **打擂法找最大值**:假设第一个是最大值,遇到更大的就更新
|
|
|
|
|
+45. **数组求和**:遍历数组,累加每个元素
|
|
|
|
|
+46. **倒序输出**:从 `length-1` 到 `0` 递减遍历
|
|
|
|
|
+47. **奇偶判断**:`n % 2 == 0` 偶,`n % 2 != 0` 奇
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
-## 十、知识拓展
|
|
|
|
|
|
|
+## 十一、知识拓展
|
|
|
|
|
|
|
|
### 1. 数组的地址值
|
|
### 1. 数组的地址值
|
|
|
|
|
|
|
@@ -878,7 +1014,7 @@ System.out.println(a); // 输出类似:[I@b4c966a
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
-## 十一、完整代码汇总
|
|
|
|
|
|
|
+## 十二、完整代码汇总
|
|
|
|
|
|
|
|
### Demo01.java — 多维数组
|
|
### Demo01.java — 多维数组
|
|
|
|
|
|
|
@@ -1184,6 +1320,99 @@ public class Demo06 {
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
+### Demo07.java — Scanner 键盘输入
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+import java.util.Scanner;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * @author WanJl
|
|
|
|
|
+ * @version 1.0
|
|
|
|
|
+ * @title Demo07
|
|
|
|
|
+ * @description Scanner键盘输入
|
|
|
|
|
+ * @create 2026/7/16
|
|
|
|
|
+ */
|
|
|
|
|
+public class Demo07 {
|
|
|
|
|
+ /*
|
|
|
|
|
+ Java中实现键盘输入的标准方式就是 Scanner 类
|
|
|
|
|
+ 它是 java.util 包下的一个工具类,可以读取我们在控制台中输入的数据
|
|
|
|
|
+ 操作步骤:
|
|
|
|
|
+ 1、导包 import java.util.Scanner
|
|
|
|
|
+ 2、创建 Scanner 对象
|
|
|
|
|
+ 格式:Scanner sc = new Scanner(System.in);
|
|
|
|
|
+ 3、调用方法读取数据
|
|
|
|
|
+ |- nextByte() / nextShort() / nextInt() / nextLong()
|
|
|
|
|
+ |- nextFloat() / nextDouble()
|
|
|
|
|
+ |- next() 读取单个字符串(空格/换行符结束)
|
|
|
|
|
+ |- nextLine() 读取整行字符串(换行符结束)
|
|
|
|
|
+ |- nextBoolean() 读取布尔值
|
|
|
|
|
+ |- next().charAt(0) 读取字符
|
|
|
|
|
+ 4、关闭 Scanner sc.close();
|
|
|
|
|
+ */
|
|
|
|
|
+ public static void main(String[] args) {
|
|
|
|
|
+ Scanner sc = new Scanner(System.in);
|
|
|
|
|
+
|
|
|
|
|
+ /*
|
|
|
|
|
+ Scanner有陷阱:
|
|
|
|
|
+ nextInt()后面使用nextLine()的问题
|
|
|
|
|
+ 原因:nextInt()读取完数字后,换行符还停留在缓冲区中,
|
|
|
|
|
+ 紧接着的nextLine()遇到了换行符就直接结束了
|
|
|
|
|
+ */
|
|
|
|
|
+ // 解决方案:在nextInt()之后调用一次nextLine() 吃掉换行符
|
|
|
|
|
+ int a = sc.nextInt();
|
|
|
|
|
+ sc.nextLine(); // 吃掉换行符
|
|
|
|
|
+ String s = sc.nextLine();
|
|
|
|
|
+
|
|
|
|
|
+ System.out.println(a);
|
|
|
|
|
+ System.out.println(s);
|
|
|
|
|
+ sc.close();
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### Demo08.java — Scanner 练习
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+import java.util.Scanner;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * @author WanJl
|
|
|
|
|
+ * @version 1.0
|
|
|
|
|
+ * @title Demo08
|
|
|
|
|
+ * @description Scanner练习
|
|
|
|
|
+ * @create 2026/7/16
|
|
|
|
|
+ */
|
|
|
|
|
+public class Demo08 {
|
|
|
|
|
+ public static void main(String[] args) {
|
|
|
|
|
+ // 1、创建Scanner对象
|
|
|
|
|
+ Scanner sc = new Scanner(System.in);
|
|
|
|
|
+
|
|
|
|
|
+ // 2、读取不同类型的数据
|
|
|
|
|
+ System.out.println("请输入您的姓名:");
|
|
|
|
|
+ String name = sc.next();
|
|
|
|
|
+
|
|
|
|
|
+ System.out.println("请输入您的年龄:");
|
|
|
|
|
+ int age = sc.nextInt();
|
|
|
|
|
+
|
|
|
|
|
+ System.out.println("请输入您的身高(米):");
|
|
|
|
|
+ double height = sc.nextDouble();
|
|
|
|
|
+
|
|
|
|
|
+ System.out.println("您是否是在校学生(true/false):");
|
|
|
|
|
+ boolean isStudent = sc.nextBoolean();
|
|
|
|
|
+
|
|
|
|
|
+ // 3、输出用户信息
|
|
|
|
|
+ System.out.println("\n========用户信息========");
|
|
|
|
|
+ System.out.println("姓名:" + name);
|
|
|
|
|
+ System.out.println("年龄:" + age);
|
|
|
|
|
+ System.out.println("身高:" + height);
|
|
|
|
|
+ System.out.println("在校学生:" + isStudent);
|
|
|
|
|
+
|
|
|
|
|
+ // 4、关闭Scanner 释放资源
|
|
|
|
|
+ sc.close();
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
### Exercises01.java — 首尾对称交换
|
|
### Exercises01.java — 首尾对称交换
|
|
|
|
|
|
|
|
```java
|
|
```java
|
|
@@ -1406,7 +1635,7 @@ public class HomeWork10 {
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
-## 十二、拓展阅读
|
|
|
|
|
|
|
+## 十三、拓展阅读
|
|
|
|
|
|
|
|
| 概念 | 说明 |
|
|
| 概念 | 说明 |
|
|
|
|------|------|
|
|
|------|------|
|
|
@@ -1445,6 +1674,18 @@ public class HomeWork10 {
|
|
|
| **插入排序-稳定性** | ✅ 稳定 |
|
|
| **插入排序-稳定性** | ✅ 稳定 |
|
|
|
| **插入排序-实用性** | 三种基础 O(n²) 排序中最实用,小规模数据首选 |
|
|
| **插入排序-实用性** | 三种基础 O(n²) 排序中最实用,小规模数据首选 |
|
|
|
| **三种排序对比** | 实用性:插入 > 选择 > 冒泡;稳定性:冒泡 ✅、插入 ✅、选择 ❌ |
|
|
| **三种排序对比** | 实用性:插入 > 选择 > 冒泡;稳定性:冒泡 ✅、插入 ✅、选择 ❌ |
|
|
|
|
|
+| **Scanner 键盘输入** | `java.util.Scanner` 类,用于读取控制台输入 |
|
|
|
|
|
+| **Scanner 导包** | `import java.util.Scanner;` |
|
|
|
|
|
+| **Scanner 创建对象** | `Scanner sc = new Scanner(System.in);` |
|
|
|
|
|
+| **Scanner 关闭** | `sc.close();` 释放资源 |
|
|
|
|
|
+| **Scanner-nextInt()** | 读取 int 类型整数 |
|
|
|
|
|
+| **Scanner-nextDouble()** | 读取 double 类型小数 |
|
|
|
|
|
+| **Scanner-next()** | 读取单个字符串,以空格/换行结束 |
|
|
|
|
|
+| **Scanner-nextLine()** | 读取整行字符串,以换行结束 |
|
|
|
|
|
+| **Scanner-nextBoolean()** | 读取 boolean 类型值(true/false) |
|
|
|
|
|
+| **Scanner 陷阱** | `nextInt()` 后用 `nextLine()` 会读取到空字符串(缓冲区残留换行符) |
|
|
|
|
|
+| **Scanner 陷阱解决** | 在 `nextInt()` 后调用一次 `nextLine()` 吃掉换行符 |
|
|
|
|
|
+| **Scanner 类型不匹配** | 输入类型与接收类型不符时抛出 `InputMismatchException` |
|
|
|
| **变量交换-临时变量** | `tmp = a; a = b; b = tmp;` 最直观的交换方式 |
|
|
| **变量交换-临时变量** | `tmp = a; a = b; b = tmp;` 最直观的交换方式 |
|
|
|
| **变量交换-加减法** | `a = a + b; b = a - b; a = a - b;` 不借助第三个变量 |
|
|
| **变量交换-加减法** | `a = a + b; b = a - b; a = a - b;` 不借助第三个变量 |
|
|
|
| **数组循环右移** | 从后往前逐位移动,保存最后一位到第一位,外层套循环控制移动次数 |
|
|
| **数组循环右移** | 从后往前逐位移动,保存最后一位到第一位,外层套循环控制移动次数 |
|