Java常用类详解
Java 常用类详解
本章位置:Java 核心基础
学习目标:掌握String、StringBuilder、包装类、Math、Random、BigDecimal、System、日期时间 API、正则表达式等常用类,并能够在实际业务代码中正确选择和使用。
一、为什么要学习 Java 常用类
学习面向对象之后,我们已经知道:
Java 中很多功能都是通过类和对象提供的
实际开发时,不可能所有功能都自己从零实现。
例如:
字符串处理
数学运算
随机数
金额计算
日期时间
类型转换
数组操作
正则校验
Java 标准库已经提供了大量可以直接使用的类。
例如:
String
StringBuilder
Integer
Double
Math
Random
BigDecimal
System
LocalDate
LocalDateTime
DateTimeFormatter
Pattern
这些类通常被统称为:
Java 常用类
二、Java API 是什么
API:
Application Programming Interface
可以理解为:
Java 官方已经写好的类、方法和功能,我们按照规定的方式调用即可。
例如:
Math.max(10, 20);
我们不需要自己重新编写“求最大值”的底层逻辑。
三、学习常用类的正确方式
常用类很多,不需要死记所有方法。
建议掌握:
1. 这个类解决什么问题
2. 常用方法有哪些
3. 方法返回什么
4. 哪些地方容易踩坑
5. 不熟悉时会查 API 文档
实际开发中:
记住核心用法
+
需要时查询官方文档
比死背几十个方法更加重要。
四、String 字符串
Java 中:
String
用于表示字符串。
例如:
String name = "张三";
String message = "Hello Java";
注意:
String 不是 Java 的 8 种基本数据类型
它是一个:
引用类型
五、创建 String
最常见:
String name = "张三";
也可以:
String name =
new String("张三");
实际开发中一般优先使用:
String name = "张三";
六、字符串不可变
String 最重要的特点之一:
String 对象一旦创建,它保存的字符串内容本身不能被修改。
例如:
String str = "Java";
str = str + " Web";
看起来好像:
Java
被改成:
Java Web
实际上通常可以理解为:
创建了新的字符串对象
然后让 str 指向新的对象
原来的:
"Java"
并没有被直接修改。
七、为什么 String 设计成不可变
不可变带来很多好处:
安全
线程安全
字符串常量池可复用
hash 值稳定
便于作为 Map 键
初学阶段重点记住:
对 String 做“修改”操作时,经常是在产生新字符串。
八、字符串常量池
例如:
String s1 = "Java";
String s2 = "Java";
字符串字面量:
"Java"
通常会进入:
字符串常量池
相同字面量有机会被复用。
因此:
System.out.println(s1 == s2);
可能得到:
true
但不要因此养成用 == 比较字符串内容的习惯。
九、== 和 equals() 比较字符串
这是 Java 初学阶段非常重要的知识点。
==
对于引用类型:
主要比较是否指向同一个对象
equals()
String 重写了:
equals()
用于比较:
字符串内容是否相同
例如:
String s1 =
new String("Java");
String s2 =
new String("Java");
System.out.println(
s1 == s2
);
System.out.println(
s1.equals(s2)
);
通常输出:
false
true
十、字符串比较推荐写法
例如:
String username = "admin";
判断:
if ("admin".equals(username)) {
}
这种写法有一个好处:
即使:
username == null
也不会因为调用:
username.equals(...)
出现空指针。
十一、equalsIgnoreCase()
忽略英文字母大小写比较:
String a = "JAVA";
String b = "java";
System.out.println(
a.equalsIgnoreCase(b)
);
输出:
true
常用于:
验证码之外的普通英文输入
命令
扩展名
简单标识
十二、String.length()
获取字符串长度:
String text = "Java";
System.out.println(
text.length()
);
输出:
4
注意和数组区别:
数组:
array.length
字符串:
str.length()
一个没有括号,一个有括号。
十三、charAt()
获取指定索引位置的字符:
String text = "Java";
char c = text.charAt(0);
System.out.println(c);
输出:
J
索引同样从:
0
开始。
十四、遍历字符串
String text = "Java";
for (int i = 0;
i < text.length();
i++) {
System.out.println(
text.charAt(i)
);
}
输出:
J
a
v
a
十五、isEmpty()
判断字符串长度是不是 0:
String str = "";
System.out.println(
str.isEmpty()
);
输出:
true
注意:
""
和:
null
不是一回事。
十六、空字符串和 null
空字符串
String str = "";
说明:
对象存在
但内容长度是 0
null
String str = null;
说明:
没有指向实际 String 对象
所以:
str.length();
会出现:
NullPointerException
十七、isBlank()
Java 11 以后:
isBlank()
可以判断:
空字符串
或只包含空白字符
例如:
System.out.println(
"".isBlank()
);
System.out.println(
" ".isBlank()
);
都是:
true
十八、contains()
判断是否包含某段内容:
String text =
"学习 Java SpringBoot";
System.out.println(
text.contains("Java")
);
输出:
true
十九、startsWith() 和 endsWith()
判断开头:
String file =
"avatar.jpg";
System.out.println(
file.startsWith("avatar")
);
判断结尾:
System.out.println(
file.endsWith(".jpg")
);
常见用途:
文件后缀判断
URL 判断
字符串前缀匹配
二十、indexOf()
查找某个字符或字符串第一次出现的索引:
String text =
"hello java";
int index =
text.indexOf("java");
System.out.println(index);
如果找不到:
返回 -1
例如:
System.out.println(
text.indexOf("python")
);
结果:
-1
二十一、lastIndexOf()
查找最后一次出现的位置:
String text =
"a-b-c-b";
System.out.println(
text.lastIndexOf("b")
);
二十二、substring()
截取字符串。
例如:
String text =
"HelloJava";
String result =
text.substring(5);
System.out.println(result);
输出:
Java
二十三、substring(begin, end)
例如:
String text =
"HelloJava";
String result =
text.substring(
0,
5
);
输出:
Hello
规则:
包含 begin
不包含 end
也就是常说的:
左闭右开
二十四、replace()
替换字符串:
String text =
"Java is good";
String result =
text.replace(
"Java",
"Spring"
);
结果:
Spring is good
原字符串不会直接改变。
二十五、replaceAll()
replaceAll() 支持:
正则表达式
例如:
String text =
"abc123def456";
String result =
text.replaceAll(
"\\d+",
"*"
);
结果类似:
abc*def*
二十六、toUpperCase() 和 toLowerCase()
转大写:
String text = "java";
System.out.println(
text.toUpperCase()
);
结果:
JAVA
转小写:
"JAVA".toLowerCase()
结果:
java
二十七、trim()
去掉字符串:
首尾传统空格
例如:
String text =
" Java ";
System.out.println(
text.trim()
);
结果:
Java
二十八、strip()
Java 11 以后:
strip()
对 Unicode 空白字符处理更完善。
例如:
String result =
text.strip();
现代 Java 中通常更推荐理解和使用:
strip()
二十九、split()
按照指定规则切割字符串。
例如:
String text =
"Java,MySQL,Spring";
String[] array =
text.split(",");
遍历:
for (String item : array) {
System.out.println(item);
}
输出:
Java
MySQL
Spring
三十、split() 参数是正则表达式
这是容易踩坑的地方。
例如:
.
|
+
*
等字符在正则中有特殊含义。
如果按点切割:
String ip =
"192.168.1.1";
不能简单写:
ip.split(".");
应该:
ip.split("\\.");
三十一、String.join()
拼接多个字符串:
String result =
String.join(
"-",
"2026",
"09",
"09"
);
结果:
2026-09-09
三十二、String.valueOf()
把其他类型转换成字符串:
int age = 20;
String text =
String.valueOf(age);
例如:
String.valueOf(3.14);
String.valueOf(true);
都很常用。
三十三、toCharArray()
字符串转换成字符数组:
String text =
"Java";
char[] chars =
text.toCharArray();
然后:
for (char c : chars) {
System.out.println(c);
}
三十四、字符串反转
String 本身没有直接:
reverse()
可以借助:
StringBuilder
例如:
String text =
"Java";
String result =
new StringBuilder(text)
.reverse()
.toString();
System.out.println(result);
结果:
avaJ
三十五、StringBuilder
StringBuilder 用于:
高效地进行字符串拼接和修改
例如:
StringBuilder builder =
new StringBuilder();
添加:
builder.append("Java");
builder.append(" ");
builder.append("Spring");
最终:
String result =
builder.toString();
三十六、为什么需要 StringBuilder
如果循环中大量使用:
String result = "";
for (...) {
result = result + ...
}
可能不断创建新的 String 对象。
例如:
String result = "";
for (int i = 0;
i < 1000;
i++) {
result += i;
}
大量拼接时效率较低。
更适合:
StringBuilder builder =
new StringBuilder();
for (int i = 0;
i < 1000;
i++) {
builder.append(i);
}
三十七、StringBuilder.append()
追加内容:
StringBuilder sb =
new StringBuilder();
sb.append("姓名:");
sb.append("张三");
sb.append(", 年龄:");
sb.append(20);
也可以链式调用:
sb.append("姓名:")
.append("张三")
.append(", 年龄:")
.append(20);
三十八、StringBuilder.insert()
在指定位置插入:
StringBuilder sb =
new StringBuilder(
"Java"
);
sb.insert(
4,
" Web"
);
结果:
Java Web
三十九、StringBuilder.delete()
删除指定区间:
StringBuilder sb =
new StringBuilder(
"Hello Java"
);
sb.delete(
0,
6
);
结果:
Java
同样是:
左闭右开
四十、StringBuilder.deleteCharAt()
删除某一个字符:
sb.deleteCharAt(0);
四十一、StringBuilder.replace()
替换指定区间:
StringBuilder sb =
new StringBuilder(
"Hello Java"
);
sb.replace(
6,
10,
"Spring"
);
结果:
Hello Spring
四十二、StringBuilder.reverse()
反转:
StringBuilder sb =
new StringBuilder(
"Java"
);
sb.reverse();
System.out.println(sb);
输出:
avaJ
四十三、StringBuilder.length()
sb.length()
获取当前字符数量。
四十四、StringBuilder 和 String 互转
String → StringBuilder:
StringBuilder sb =
new StringBuilder(
"Java"
);
StringBuilder → String:
String text =
sb.toString();
四十五、StringBuffer
StringBuffer 和 StringBuilder 的功能非常相似。
例如:
StringBuffer buffer =
new StringBuffer();
buffer.append("Java");
核心区别可以先记:
StringBuilder
通常更快
非线程安全
StringBuffer
方法带同步处理
线程安全性更高
现代普通业务代码中:
StringBuilder 使用更频繁
四十六、String、StringBuilder、StringBuffer 对比
| 类型 | 是否可变 | 线程安全 | 常见用途 |
|---|---|---|---|
String |
不可变 | 天然较安全 | 普通字符串 |
StringBuilder |
可变 | 否 | 单线程大量拼接 |
StringBuffer |
可变 | 较安全 | 特殊多线程场景 |
日常可以先记:
普通字符串 → String
大量拼接 → StringBuilder
四十七、包装类
Java 有 8 种基本数据类型。
每一种基本类型都有对应包装类。
| 基本类型 | 包装类 |
|---|---|
byte |
Byte |
short |
Short |
int |
Integer |
long |
Long |
float |
Float |
double |
Double |
char |
Character |
boolean |
Boolean |
四十八、为什么需要包装类
因为很多 Java API:
只能操作对象
不能直接操作基本类型
例如后面的集合:
ArrayList<Integer>
不能写:
ArrayList<int>
所以需要:
Integer
包装 int。
四十九、装箱和拆箱
基本类型:
int number = 10;
变成包装类:
Integer value = number;
叫:
自动装箱
包装类变回基本类型:
int result = value;
叫:
自动拆箱
五十、自动装箱
以前可以显式:
Integer value =
Integer.valueOf(10);
现在通常:
Integer value = 10;
Java 自动处理。
五十一、包装类不能忽视 null
基本类型:
int
不能为:
null
但:
Integer
可以:
Integer number = null;
如果自动拆箱:
int value = number;
会出现:
NullPointerException
这是实际开发中非常常见的问题。
五十二、Integer.parseInt()
把数字字符串转换成:
int
例如:
String text = "123";
int number =
Integer.parseInt(text);
结果:
123
五十三、其他 parse 方法
Long.parseLong("100");
Double.parseDouble("3.14");
Float.parseFloat("3.14");
Boolean.parseBoolean("true");
五十四、NumberFormatException
如果:
Integer.parseInt("abc");
无法转成整数,
会出现:
NumberFormatException
它属于异常机制,下一章会详细学习。
五十五、Integer.valueOf()
Integer value =
Integer.valueOf("123");
得到的是:
Integer
而:
Integer.parseInt("123")
得到的是:
int
五十六、Integer 常量
常见:
Integer.MAX_VALUE
表示:
int 最大值
Integer.MIN_VALUE
表示:
int 最小值
例如:
System.out.println(
Integer.MAX_VALUE
);
五十七、进制转换
十进制转二进制:
Integer.toBinaryString(10);
结果:
1010
转十六进制:
Integer.toHexString(255);
结果:
ff
转八进制:
Integer.toOctalString(10);
五十八、Character 常用方法
判断是不是数字:
Character.isDigit('8');
判断是不是字母:
Character.isLetter('A');
判断大写:
Character.isUpperCase('A');
判断小写:
Character.isLowerCase('a');
转换:
Character.toUpperCase('a');
结果:
A
五十九、包装类缓存简单了解
例如:
Integer a = 100;
Integer b = 100;
System.out.println(a == b);
可能得到:
true
而:
Integer a = 200;
Integer b = 200;
== 的结果不要依赖。
原因涉及:
包装类缓存
因此包装类比较内容:
a.equals(b)
更加稳妥。
不要因为小整数测试通过,就用:
==
比较包装类业务值。
六十、Math 类
Math 提供大量数学计算方法。
特点:
大多数方法都是 static
所以不需要:
new Math()
直接:
Math.xxx()
六十一、Math.abs()
绝对值:
Math.abs(-10)
结果:
10
六十二、Math.max() 和 Math.min()
最大值:
Math.max(10, 20)
结果:
20
最小值:
Math.min(10, 20)
六十三、Math.pow()
幂运算:
Math.pow(2, 3)
结果:
8.0
返回通常是:
double
六十四、Math.sqrt()
平方根:
Math.sqrt(16)
结果:
4.0
六十五、Math.ceil()
向上取整:
Math.ceil(3.1)
结果:
4.0
六十六、Math.floor()
向下取整:
Math.floor(3.9)
结果:
3.0
六十七、Math.round()
四舍五入:
Math.round(3.6)
结果:
4
例如:
Math.round(3.4)
结果:
3
注意不同数值类型对应返回类型略有区别。
六十八、Math.random()
生成:
0.0 <= 随机数 < 1.0
例如:
double random =
Math.random();
六十九、生成指定范围随机整数
生成:
0 ~ 9
int number =
(int) (
Math.random()
* 10
);
生成:
1 ~ 10
int number =
(int) (
Math.random()
* 10
) + 1;
七十、Random 类
除了:
Math.random()
Java 还提供:
java.util.Random
例如:
import java.util.Random;
Random random =
new Random();
七十一、Random.nextInt()
int number =
random.nextInt(10);
生成范围:
0 ~ 9
七十二、Random 生成 1 ~ 100
int number =
random.nextInt(100)
+ 1;
范围:
1 ~ 100
七十三、Random.nextBoolean()
boolean value =
random.nextBoolean();
随机产生:
true
false
七十四、Random.nextDouble()
double value =
random.nextDouble();
七十五、ThreadLocalRandom 简单了解
在并发程序中经常看到:
ThreadLocalRandom
例如:
import java.util.concurrent
.ThreadLocalRandom;
int number =
ThreadLocalRandom
.current()
.nextInt(
1,
101
);
范围:
1 ~ 100
后面学习多线程时再深入。
七十六、BigDecimal
金额计算中一个非常重要的类:
java.math.BigDecimal
为什么需要它?
看:
System.out.println(
0.1 + 0.2
);
结果可能是:
0.30000000000000004
这和浮点数底层表示有关。
七十七、金额为什么不推荐直接 double
例如:
double price = 0.1;
double total =
price + 0.2;
涉及:
金额
金融
结算
高精度小数
时,精度误差可能不可接受。
因此常使用:
BigDecimal
七十八、正确创建 BigDecimal
推荐:
BigDecimal a =
new BigDecimal("0.1");
BigDecimal b =
new BigDecimal("0.2");
或者:
BigDecimal a =
BigDecimal.valueOf(0.1);
不推荐直接:
new BigDecimal(0.1);
因为可能把 double 本身的精度误差带进去。
七十九、BigDecimal 加法
BigDecimal result =
a.add(b);
八十、BigDecimal 减法
BigDecimal result =
a.subtract(b);
八十一、BigDecimal 乘法
BigDecimal result =
a.multiply(b);
八十二、BigDecimal 除法
BigDecimal result =
a.divide(b);
但是某些无法整除的小数:
1 / 3
如果不指定精度,可能抛异常。
因此实际开发常写:
BigDecimal result =
a.divide(
b,
2,
RoundingMode.HALF_UP
);
八十三、RoundingMode
需要:
import java.math.RoundingMode;
常见:
RoundingMode.HALF_UP
可以理解为常见的:
四舍五入
八十四、BigDecimal setScale()
保留小数位:
BigDecimal money =
new BigDecimal(
"12.345"
);
BigDecimal result =
money.setScale(
2,
RoundingMode.HALF_UP
);
结果:
12.35
八十五、BigDecimal 比较不能只看 equals()
例如:
BigDecimal a =
new BigDecimal("1.0");
BigDecimal b =
new BigDecimal("1.00");
equals() 还会考虑:
scale
所以:
a.equals(b)
可能是:
false
八十六、BigDecimal compareTo()
业务金额比较通常更常用:
a.compareTo(b)
返回:
负数 → a < b
0 → a == b
正数 → a > b
例如:
if (a.compareTo(b) == 0) {
System.out.println(
"金额相等"
);
}
八十七、BigDecimal 常见金额案例
BigDecimal price =
new BigDecimal(
"19.90"
);
BigDecimal count =
new BigDecimal(
"3"
);
BigDecimal total =
price.multiply(count);
System.out.println(total);
结果:
59.70
八十八、System 类
System 提供很多系统级功能。
常见:
标准输入输出
获取时间
数组复制
系统属性
程序退出
八十九、System.out
平时最常用:
System.out.println();
其中:
System
类
out
静态成员
println
方法
九十、System.currentTimeMillis()
获取当前时间戳:
long time =
System.currentTimeMillis();
单位:
毫秒
它常用于:
简单性能测试
生成时间相关值
记录时间
九十一、简单计算代码运行耗时
long start =
System.currentTimeMillis();
for (int i = 0;
i < 1_000_000;
i++) {
}
long end =
System.currentTimeMillis();
System.out.println(
"耗时:"
+ (end - start)
+ "ms"
);
更精细的性能测试还有专门工具,不应只依赖这种方式。
九十二、System.nanoTime()
适合:
测量时间间隔
例如:
long start =
System.nanoTime();
后面再减。
不要把它直接理解成:
当前日期时间
九十三、System.arraycopy()
数组章节已经学过:
System.arraycopy(
source,
sourcePos,
target,
targetPos,
length
);
用于高效复制数组。
九十四、System.exit()
System.exit(0);
可以终止 JVM 进程。
参数:
0
通常表示正常退出。
一般业务开发中不要随意使用。
九十五、Objects 工具类
Java 提供:
java.util.Objects
帮助处理对象。
例如:
Objects.equals(a, b)
九十六、Objects.equals()
安全比较两个对象:
String a = null;
String b = null;
System.out.println(
Objects.equals(a, b)
);
结果:
true
它可以很好地处理:
null
九十七、Objects.isNull() 和 nonNull()
Objects.isNull(obj);
判断:
obj == null
Objects.nonNull(obj);
判断:
obj != null
在 Stream 等场景也经常出现。
九十八、Objects.requireNonNull()
用于要求参数不能为空:
this.name =
Objects.requireNonNull(
name,
"name 不能为空"
);
如果:
name == null
会抛出异常。
九十九、Optional 简单了解
Java 8 提供:
Optional<T>
它用于表达:
一个值可能存在,也可能不存在
例如:
Optional<String> optional =
Optional.of("Java");
一百、Optional.ofNullable()
允许传入:
null
例如:
Optional<String> optional =
Optional.ofNullable(
name
);
一百零一、Optional.orElse()
如果值不存在,提供默认值:
String result =
optional.orElse(
"未知"
);
一百零二、Optional.ifPresent()
如果存在就执行:
optional.ifPresent(
value ->
System.out.println(
value
)
);
Lambda 会在后续阶段专门学习。
当前先知道 Optional 主要用于:
减少一些显式 null 判断
表达值可能为空
不要把 Optional 当成所有 null 问题的万能替代品。
一百零三、日期时间类发展
Java 日期时间 API 大致经历:
Date
Calendar
↓
Java 8 java.time
现代 Java 开发中更推荐:
java.time
常见:
LocalDate
LocalTime
LocalDateTime
Instant
Duration
Period
DateTimeFormatter
一百零四、Date 类简单了解
旧 API:
java.util.Date
例如:
Date date =
new Date();
System.out.println(date);
仍然会在旧项目中看到。
但新代码一般优先:
java.time
一百零五、LocalDate
表示:
日期
例如:
2026-09-09
不包含具体时间。
创建当前日期:
LocalDate today =
LocalDate.now();
需要:
import java.time.LocalDate;
一百零六、指定 LocalDate
LocalDate date =
LocalDate.of(
2026,
9,
9
);
一百零七、LocalDate 获取年月日
date.getYear();
date.getMonthValue();
date.getDayOfMonth();
一百零八、LocalDate 加减时间
增加一天:
date.plusDays(1);
增加一个月:
date.plusMonths(1);
增加一年:
date.plusYears(1);
减少:
date.minusDays(1);
注意这些对象同样是不可变设计。
需要接收返回结果:
date =
date.plusDays(1);
一百零九、LocalTime
表示:
时间
例如:
15:30:20
获取当前:
LocalTime time =
LocalTime.now();
一百一十、LocalDateTime
表示:
日期 + 时间
例如:
LocalDateTime now =
LocalDateTime.now();
常见数据库字段:
创建时间
更新时间
支付时间
登录时间
经常会用:
LocalDateTime
一百一十一、创建指定 LocalDateTime
LocalDateTime time =
LocalDateTime.of(
2026,
9,
9,
15,
30,
0
);
一百一十二、DateTimeFormatter
用于:
日期时间格式化
导入:
import java.time.format
.DateTimeFormatter;
例如:
DateTimeFormatter formatter =
DateTimeFormatter
.ofPattern(
"yyyy-MM-dd HH:mm:ss"
);
一百一十三、LocalDateTime 格式化成字符串
LocalDateTime now =
LocalDateTime.now();
String text =
now.format(
DateTimeFormatter
.ofPattern(
"yyyy-MM-dd HH:mm:ss"
)
);
输出类似:
2026-09-09 15:30:00
一百一十四、字符串解析成 LocalDate
String text =
"2026-09-09";
LocalDate date =
LocalDate.parse(
text,
DateTimeFormatter
.ofPattern(
"yyyy-MM-dd"
)
);
一百一十五、字符串解析成 LocalDateTime
String text =
"2026-09-09 15:30:00";
DateTimeFormatter formatter =
DateTimeFormatter
.ofPattern(
"yyyy-MM-dd HH:mm:ss"
);
LocalDateTime time =
LocalDateTime.parse(
text,
formatter
);
一百一十六、日期格式中的常见字母
常见:
yyyy 年
MM 月
dd 日
HH 24 小时制小时
mm 分钟
ss 秒
例如:
yyyy-MM-dd HH:mm:ss
注意:
MM 是月
mm 是分钟
非常容易写错。
一百一十七、Period
用于计算:
日期之间的年月日差
例如:
LocalDate start =
LocalDate.of(
2000,
1,
1
);
LocalDate end =
LocalDate.of(
2026,
9,
9
);
Period period =
Period.between(
start,
end
);
获取:
period.getYears();
period.getMonths();
period.getDays();
一百一十八、Duration
用于表示:
时间之间的间隔
例如:
LocalDateTime start =
LocalDateTime.now();
LocalDateTime end =
start.plusHours(2);
Duration duration =
Duration.between(
start,
end
);
获取小时:
duration.toHours();
一百一十九、Instant
Instant 表示:
UTC 时间线上的时间点
例如:
Instant now =
Instant.now();
它在:
服务端时间
时间戳
跨时区系统
中比较常见。
初学阶段先知道即可。
一百二十、时区 ZoneId 简单了解
不同地区有不同:
时区
例如:
ZoneId zone =
ZoneId.of(
"Asia/Shanghai"
);
或者:
Asia/Tokyo
跨地区系统不能简单假设:
所有用户时间都一样
后端项目中时间设计是很重要的问题。
一百二十一、UUID
Java 常用:
java.util.UUID
生成全局唯一标识。
例如:
String id =
UUID.randomUUID()
.toString();
System.out.println(id);
输出类似:
550e8400-e29b-41d4-a716-446655440000
一百二十二、去掉 UUID 中的横线
String id =
UUID.randomUUID()
.toString()
.replace(
"-",
""
);
一百二十三、UUID 常见用途
例如:
临时文件名
请求标识
业务流水辅助标识
随机 token 的组成部分
但数据库主键如何设计不能只因为“UUID 唯一”就随便决定。
主键选择需要结合:
索引
存储
分布式系统
业务规则
综合考虑。
一百二十四、正则表达式
正则表达式:
Regular Expression
用于描述:
字符串匹配规则
常见用途:
手机号格式
邮箱格式
密码规则
身份证格式
数据提取
文本替换
文本切割
一百二十五、String.matches()
简单正则判断:
String phone =
"13812345678";
boolean result =
phone.matches(
"1\\d{10}"
);
如果符合:
1 开头
后面 10 位数字
得到:
true
一百二十六、常见正则符号
\d
数字
\w
字母、数字、下划线等单词字符
\s
空白字符
.
任意字符(通常不含换行,具体模式可变)
在 Java 字符串中:
\
本身也需要转义。
所以正则:
\d
在 Java 中经常写:
"\\d"
一百二十七、数量词
* 0 次或多次
+ 1 次或多次
? 0 次或 1 次
{n} 正好 n 次
{n,} 至少 n 次
{n,m} n 到 m 次
例如:
"\\d{6}"
表示:
连续 6 位数字
一百二十八、字符范围
例如:
[abc]
a、b、c 中任意一个
[a-z]
小写字母
[A-Z]
大写字母
[0-9]
数字
一百二十九、手机号基础正则
简化版本:
String regex =
"1[3-9]\\d{9}";
使用:
boolean result =
phone.matches(regex);
注意:
手机号规则可能随业务和运营商规则变化,不应把简单教学正则当成永久权威规则。
一百三十、用户名校验
例如要求:
4 ~ 16 位
字母、数字、下划线
可以:
String regex =
"[A-Za-z0-9_]{4,16}";
一百三十一、Pattern 和 Matcher
复杂正则处理可以使用:
Pattern
Matcher
例如:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
Pattern pattern =
Pattern.compile(
"\\d+"
);
Matcher matcher =
pattern.matcher(
"订单1001金额299"
);
一百三十二、Matcher.find()
查找多个匹配:
while (matcher.find()) {
System.out.println(
matcher.group()
);
}
输出:
1001
299
一百三十三、正则不要滥用
有些简单判断:
str.isEmpty()
str.contains()
str.startsWith()
用普通字符串 API 更直观。
不要为了显得高级,把所有字符串操作都改成正则。
正则适合:
规则匹配复杂
需要批量提取
需要复杂替换
的情况。
一百三十四、Arrays 再补充
数组章节已经学过:
Arrays.toString()
Arrays.sort()
Arrays.copyOf()
Arrays.equals()
Arrays.fill()
Arrays.binarySearch()
这里重点记住:
Arrays 是数组常用工具类
大多数方法通过:
Arrays.xxx()
直接调用。
一百三十五、Collections 和集合工具类先了解
后面学习集合框架时会遇到:
Collections
注意:
Collection
和:
Collections
不是一个东西。
现在只需要先知道:
Arrays
主要服务数组
Collections
主要服务集合
后面专门学习。
一百三十六、Enum 枚举简单回顾
枚举本质上也是特殊的类。
例如:
public enum OrderStatus {
PENDING,
PAID,
SHIPPED,
COMPLETED
}
使用:
OrderStatus status =
OrderStatus.PAID;
相比:
String status = "paid";
枚举可以减少:
拼写错误
非法状态值
魔法字符串
一百三十七、Enum.valueOf()
字符串转枚举:
OrderStatus status =
OrderStatus.valueOf(
"PAID"
);
如果字符串不存在对应枚举值,会抛异常。
一百三十八、Enum.values()
获取所有枚举值:
for (OrderStatus status
: OrderStatus.values()) {
System.out.println(status);
}
一百三十九、Class 类简单了解
每个 Java 类在运行时都有对应:
Class
对象。
例如:
Class<?> clazz =
String.class;
也可以:
student.getClass();
它是后面学习:
反射
Spring 底层
框架机制
的重要基础。
当前章节不深入。
一百四十、常用类综合案例:用户注册校验
需求:
用户名:
4 ~ 16 位字母数字下划线
密码:
至少 8 位
手机号:
简单格式校验
注册时间:
保存当前时间
用户编号:
UUID
代码:
import java.time
.LocalDateTime;
import java.time.format
.DateTimeFormatter;
import java.util.UUID;
public class RegisterDemo {
public static void main(
String[] args
) {
String username =
"java_user";
String password =
"12345678";
String phone =
"13812345678";
boolean usernameOk =
username.matches(
"[A-Za-z0-9_]{4,16}"
);
boolean passwordOk =
password.length()
>= 8;
boolean phoneOk =
phone.matches(
"1[3-9]\\d{9}"
);
if (!usernameOk) {
System.out.println(
"用户名格式错误"
);
return;
}
if (!passwordOk) {
System.out.println(
"密码至少 8 位"
);
return;
}
if (!phoneOk) {
System.out.println(
"手机号格式错误"
);
return;
}
String userId =
UUID.randomUUID()
.toString()
.replace(
"-",
""
);
String registerTime =
LocalDateTime
.now()
.format(
DateTimeFormatter
.ofPattern(
"yyyy-MM-dd HH:mm:ss"
)
);
System.out.println(
"注册成功"
);
System.out.println(
"用户编号:"
+ userId
);
System.out.println(
"注册时间:"
+ registerTime
);
}
}
一百四十一、综合案例:商品结算
需求:
商品单价 19.90
购买 3 件
优惠 5.00
计算实付金额
保留两位小数
import java.math.BigDecimal;
import java.math.RoundingMode;
public class OrderDemo {
public static void main(
String[] args
) {
BigDecimal price =
new BigDecimal(
"19.90"
);
BigDecimal count =
new BigDecimal(
"3"
);
BigDecimal discount =
new BigDecimal(
"5.00"
);
BigDecimal total =
price.multiply(count);
BigDecimal actual =
total.subtract(
discount
);
actual =
actual.setScale(
2,
RoundingMode.HALF_UP
);
System.out.println(
"商品总额:"
+ total
);
System.out.println(
"优惠金额:"
+ discount
);
System.out.println(
"实付金额:"
+ actual
);
}
}
一百四十二、综合案例:字符串统计
需求:
统计字符串中:
大写字母数量
小写字母数量
数字数量
其他字符数量
代码:
public class StringCountDemo {
public static void main(
String[] args
) {
String text =
"Java2026!Spring";
int upperCount = 0;
int lowerCount = 0;
int digitCount = 0;
int otherCount = 0;
for (int i = 0;
i < text.length();
i++) {
char c =
text.charAt(i);
if (Character
.isUpperCase(c)) {
upperCount++;
} else if (Character
.isLowerCase(c)) {
lowerCount++;
} else if (Character
.isDigit(c)) {
digitCount++;
} else {
otherCount++;
}
}
System.out.println(
"大写字母:"
+ upperCount
);
System.out.println(
"小写字母:"
+ lowerCount
);
System.out.println(
"数字:"
+ digitCount
);
System.out.println(
"其他字符:"
+ otherCount
);
}
}
一百四十三、综合案例:统计单词出现次数
例如:
java,spring,java,mysql,java,spring
暂时不使用集合,
只练习字符串和数组:
String text =
"java,spring,java,mysql,java,spring";
String[] words =
text.split(",");
int javaCount = 0;
for (String word : words) {
if ("java".equals(word)) {
javaCount++;
}
}
System.out.println(
"java 出现次数:"
+ javaCount
);
后面学习:
Map
后可以更优雅地统计所有单词次数。
一百四十四、综合案例:密码脱敏
例如手机号:
13812345678
希望显示:
138****5678
可以:
String phone =
"13812345678";
String result =
phone.substring(
0,
3
)
+ "****"
+ phone.substring(
7
);
System.out.println(result);
一百四十五、身份证或姓名脱敏思路
例如姓名:
张三
可显示:
张*
例如:
String name = "张三";
String result =
name.substring(
0,
1
)
+ "*";
真实系统还需要考虑:
不同姓名长度
Unicode 字符
隐私合规
业务规则