|
@@ -420,6 +420,16 @@ Java 中的 API 指 JDK 提供的各种功能的 Java 类,这些类把底层
|
|
|
|
|
|
|
|
包括之前使用过的 `Scanner` 键盘输入类和 `Random` 随机数类,都属于 Java 的 API。
|
|
包括之前使用过的 `Scanner` 键盘输入类和 `Random` 随机数类,都属于 Java 的 API。
|
|
|
|
|
|
|
|
|
|
+本日讲解的 API 包括:
|
|
|
|
|
+
|
|
|
|
|
+| 分类 | 类/接口 | 说明 |
|
|
|
|
|
+|------|---------|------|
|
|
|
|
|
+| **字符串** | `String` / `StringBuffer` / `StringBuilder` | 不可变字符串与可变字符串 |
|
|
|
|
|
+| **数学** | `Math` | 数学运算工具类 |
|
|
|
|
|
+| **日期时间** | `Date` / `LocalDate` / `LocalTime` / `LocalDateTime` | JDK8 前后日期时间 API |
|
|
|
|
|
+
|
|
|
|
|
+> 📄 来源:`api/Demo01.java`(已更新)
|
|
|
|
|
+
|
|
|
### 6.2 String 字符串类
|
|
### 6.2 String 字符串类
|
|
|
|
|
|
|
|
`String` 是 Java 中最常用的 API 类之一,用于处理字符串数据。
|
|
`String` 是 Java 中最常用的 API 类之一,用于处理字符串数据。
|
|
@@ -555,6 +565,182 @@ String joined = String.join("-", "A", "B", "C"); // "A-B-C"
|
|
|
|
|
|
|
|
> **注意**:`String` 类比较特殊,**打印其对象名时不会输出内存地址,而是输出该对象所记录的字符串内容**。这个特性是通过重写 `Object` 类的 `toString()` 方法实现的。
|
|
> **注意**:`String` 类比较特殊,**打印其对象名时不会输出内存地址,而是输出该对象所记录的字符串内容**。这个特性是通过重写 `Object` 类的 `toString()` 方法实现的。
|
|
|
|
|
|
|
|
|
|
+#### 6.2.5 String 的不可变性
|
|
|
|
|
+
|
|
|
|
|
+`String` 是 **不可变类(Immutable Class)**:
|
|
|
|
|
+- `String` 类被 `final` 修饰,不能被继承
|
|
|
|
|
+- 内部的字符数组/字节数组也被 `final` 修饰
|
|
|
|
|
+- **每次对 String 的修改都会创建新的对象**,原字符串对象不变
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+String s = "Hello";
|
|
|
|
|
+s = s + " World"; // 不是修改原对象,而是创建新对象并重新赋值
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+> 📄 来源:`api/Demo01.java`
|
|
|
|
|
+
|
|
|
|
|
+**开发建议**:
|
|
|
|
|
+- 字符串拼接使用 `StringBuilder`
|
|
|
|
|
+- 字符串比较使用 `equals()` 而不是 `==`
|
|
|
|
|
+- **频繁改变字符串内容时,不要使用 `String`,而应使用 `StringBuilder`**
|
|
|
|
|
+
|
|
|
|
|
+#### 6.2.6 可变字符串类(StringBuffer / StringBuilder)
|
|
|
|
|
+
|
|
|
|
|
+为了解决 String 不可变导致的频繁创建对象问题,Java 提供了两个可变字符串类:
|
|
|
|
|
+
|
|
|
|
|
+| 类 | 线程安全性 | 性能 | 使用场景 |
|
|
|
|
|
+|----|-----------|------|---------|
|
|
|
|
|
+| `StringBuffer` | **线程安全**(方法被 `synchronized` 修饰) | 较低 | 多线程环境 |
|
|
|
|
|
+| `StringBuilder` | **线程不安全** | 较高 | 单线程环境(开发中最常用) |
|
|
|
|
|
+
|
|
|
|
|
+**常用方法**:`append()` 追加内容,`toString()` 转换为 String
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+// StringBuffer —— 线程安全,性能较低
|
|
|
|
|
+StringBuffer sb = new StringBuffer();
|
|
|
|
|
+sb.append("账号");
|
|
|
|
|
+sb.append("张三");
|
|
|
|
|
+sb.append("hello");
|
|
|
|
|
+sb.append("123456");
|
|
|
|
|
+String result1 = sb.toString();
|
|
|
|
|
+System.out.println(result1);
|
|
|
|
|
+
|
|
|
|
|
+// StringBuilder —— 线程不安全,性能较高(推荐)
|
|
|
|
|
+StringBuilder sb1 = new StringBuilder();
|
|
|
|
|
+sb1.append("账号");
|
|
|
|
|
+sb1.append("张三");
|
|
|
|
|
+sb1.append("hello");
|
|
|
|
|
+sb1.append("123456");
|
|
|
|
|
+String result2 = sb1.toString();
|
|
|
|
|
+System.out.println(result2);
|
|
|
|
|
+```
|
|
|
|
|
+> 📄 来源:`api/string/StringTest03.java`
|
|
|
|
|
+
|
|
|
|
|
+#### 6.2.7 文本块(Text Block)— JDK 15+
|
|
|
|
|
+
|
|
|
|
|
+文本块使用 **三对双引号 `""" ... """`** 定义多行字符串,自动处理缩进和换行,代码更简洁清晰。
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+// 传统方式:使用 \n 拼接
|
|
|
|
|
+String s = "姓名:张三\n年龄:20\n性别:男";
|
|
|
|
|
+System.out.println(s);
|
|
|
|
|
+
|
|
|
|
|
+// 文本块方式(JDK 15+):自动去除尾部空格 + 公共缩进
|
|
|
|
|
+String s1 = """
|
|
|
|
|
+ 姓名:张三
|
|
|
|
|
+ 年龄:20
|
|
|
|
|
+ 性别:男
|
|
|
|
|
+ """;
|
|
|
|
|
+System.out.println(s1);
|
|
|
|
|
+```
|
|
|
|
|
+> 📄 来源:`api/string/StringTest03.java`
|
|
|
|
|
+
|
|
|
|
|
+### 6.4 Math 数学类
|
|
|
|
|
+
|
|
|
|
|
+`Math` 类提供了基本的数学运算方法,所有方法都是 **静态方法**,通过 `类名.方法名()` 直接调用。
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+System.out.println("π:" + Math.PI); // 3.141592653589793
|
|
|
|
|
+System.out.println("绝对值:" + Math.abs(-6)); // 6
|
|
|
|
|
+System.out.println("最大值:" + Math.max(15, 7)); // 15
|
|
|
|
|
+System.out.println("最小值:" + Math.min(15, 7)); // 7
|
|
|
|
|
+System.out.println("2的10次方:" + Math.pow(2, 10)); // 1024.0
|
|
|
|
|
+System.out.println("开根号:" + Math.sqrt(16)); // 4.0
|
|
|
|
|
+System.out.println("向上取整:" + Math.ceil(3.2)); // 4.0
|
|
|
|
|
+System.out.println("向下取整:" + Math.floor(3.2)); // 3.0
|
|
|
|
|
+System.out.println("四舍五入:" + Math.round(3.6)); // 4
|
|
|
|
|
+System.out.println("[0.0, 1.0)随机数:" + Math.random());
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Math 常用方法一览**:
|
|
|
|
|
+
|
|
|
|
|
+| 方法 | 说明 | 示例 |
|
|
|
|
|
+|------|------|------|
|
|
|
|
|
+| `Math.PI` | 圆周率常量 | `3.141592653589793` |
|
|
|
|
|
+| `abs(int a)` | 绝对值 | `abs(-6)` → `6` |
|
|
|
|
|
+| `max(int a, int b)` | 最大值 | `max(15, 7)` → `15` |
|
|
|
|
|
+| `min(int a, int b)` | 最小值 | `min(15, 7)` → `7` |
|
|
|
|
|
+| `pow(double a, double b)` | 幂运算 aᵇ | `pow(2, 10)` → `1024.0` |
|
|
|
|
|
+| `sqrt(double a)` | 平方根 | `sqrt(16)` → `4.0` |
|
|
|
|
|
+| `ceil(double a)` | 向上取整 | `ceil(3.2)` → `4.0` |
|
|
|
|
|
+| `floor(double a)` | 向下取整 | `floor(3.2)` → `3.0` |
|
|
|
|
|
+| `round(double a)` | 四舍五入 | `round(3.6)` → `4` |
|
|
|
|
|
+| `random()` | 随机数 [0.0, 1.0) | `random()` → `0.xxx` |
|
|
|
|
|
+
|
|
|
|
|
+> 📄 来源:`api/math/MathTest.java`
|
|
|
|
|
+
|
|
|
|
|
+### 6.5 日期时间类
|
|
|
|
|
+
|
|
|
|
|
+Java 中处理日期时间有两套 API:
|
|
|
|
|
+
|
|
|
|
|
+#### 6.5.1 JDK8 之前的日期类(了解)
|
|
|
|
|
+
|
|
|
|
|
+| 类 | 说明 | 缺点 |
|
|
|
|
|
+|----|------|------|
|
|
|
|
|
+| `java.util.Date` | 日期时间类 | 设计不佳,大部分方法已废弃 |
|
|
|
|
|
+| `java.text.SimpleDateFormat` | 日期格式化 | **线程不安全** |
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+Date date = new Date();
|
|
|
|
|
+System.out.println(date); // 输出当前日期时间
|
|
|
|
|
+```
|
|
|
|
|
+> 📄 来源:`api/date/DateTest.java`
|
|
|
|
|
+
|
|
|
|
|
+#### 6.5.2 JDK8 之后的新日期时间 API(推荐)
|
|
|
|
|
+
|
|
|
|
|
+`java.time` 包下的新 API,线程安全、设计优雅。
|
|
|
|
|
+
|
|
|
|
|
+##### LocalDate — 日期类(yyyy-MM-dd)
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+// 创建日期
|
|
|
|
|
+LocalDate today = LocalDate.now(); // 当前日期
|
|
|
|
|
+LocalDate date = LocalDate.of(2018, 7, 27); // 指定日期
|
|
|
|
|
+
|
|
|
|
|
+// 获取日期各部分
|
|
|
|
|
+int year = date.getYear(); // 年份
|
|
|
|
|
+int monthValue = date.getMonthValue(); // 月份 (1-12)
|
|
|
|
|
+int dayOfMonth = date.getDayOfMonth(); // 当月第几天
|
|
|
|
|
+int dayOfYear = date.getDayOfYear(); // 当年第几天
|
|
|
|
|
+DayOfWeek dayOfWeek = date.getDayOfWeek(); // 星期几
|
|
|
|
|
+
|
|
|
|
|
+// 日期加减(返回新对象,原对象不变)
|
|
|
|
|
+LocalDate date1 = date.plusDays(5); // 加5天
|
|
|
|
|
+LocalDate date2 = date.plusMonths(6); // 加6月
|
|
|
|
|
+LocalDate date3 = date.plusYears(5); // 加5年
|
|
|
|
|
+```
|
|
|
|
|
+> 📄 来源:`api/date/LocalDateTest.java`
|
|
|
|
|
+
|
|
|
|
|
+##### LocalTime — 时间类(HH:mm:ss.nnn)
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+LocalTime time = LocalTime.now(); // 当前时间
|
|
|
|
|
+LocalTime localTime = LocalTime.of(6, 20, 31); // 指定时间 06:20:31
|
|
|
|
|
+```
|
|
|
|
|
+> 📄 来源:`api/date/LocalDateTest.java`
|
|
|
|
|
+
|
|
|
|
|
+##### LocalDateTime — 日期+时间类
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+LocalDateTime ldt = LocalDateTime.now();
|
|
|
|
|
+System.out.println(ldt); // 2026-07-27T16:37:02.405
|
|
|
|
|
+
|
|
|
|
|
+// 使用 DateTimeFormatter 格式化
|
|
|
|
|
+DateTimeFormatter formatter =
|
|
|
|
|
+ DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
|
|
|
|
|
+String formatted = ldt.format(formatter);
|
|
|
|
|
+System.out.println(formatted); // 2026年07月27日 16时37分02秒
|
|
|
|
|
+```
|
|
|
|
|
+> 📄 来源:`api/date/LocalDateTest.java`
|
|
|
|
|
+
|
|
|
|
|
+##### 新旧日期时间 API 对比
|
|
|
|
|
+
|
|
|
|
|
+| 对比维度 | JDK8 之前 (`Date`/`Calendar`) | JDK8 之后 (`java.time`) |
|
|
|
|
|
+|----------|-------------------------------|------------------------|
|
|
|
|
|
+| 线程安全 | ❌ 不安全 | ✅ 线程安全(不可变类) |
|
|
|
|
|
+| 设计清晰度 | ❌ 混乱,方法命名不统一 | ✅ 清晰,职责分明 |
|
|
|
|
|
+| 常用类 | `Date`, `SimpleDateFormat` | `LocalDate`, `LocalTime`, `LocalDateTime`, `DateTimeFormatter` |
|
|
|
|
|
+
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
## 七、匿名内部类应用场景总结
|
|
## 七、匿名内部类应用场景总结
|