文章目录
- [Ⅰ. Stream API](#Ⅰ. Stream API)
-
- [一、Stream 创建方式](#一、Stream 创建方式)
- [二、中间操作(返回新的 Stream,可链式调用)](#二、中间操作(返回新的 Stream,可链式调用))
- 三、终止操作(触发流处理,返回具体结果)
- [Ⅱ. Optional 类](#Ⅱ. Optional 类)
- [Ⅲ. 两者结合的一个例子](#Ⅲ. 两者结合的一个例子)
- [Ⅳ. 正则表达式](#Ⅳ. 正则表达式)
-
- [🧠 1. 基础元字符(Metacharacters)](#🧠 1. 基础元字符(Metacharacters))
- [📚 2. 常用转义字符](#📚 2. 常用转义字符)
- [🔐 3. 常用校验正则(可直接用于 Java)](#🔐 3. 常用校验正则(可直接用于 Java))
-
- [✅ 邮箱](#✅ 邮箱)
- [✅ 手机号(中国大陆)](#✅ 手机号(中国大陆))
- [✅ 身份证(大陆 18位)](#✅ 身份证(大陆 18位))
- [✅ 密码强度(6-12位,字母或数字)](#✅ 密码强度(6-12位,字母或数字))
- [✅ 密码必须包含大小写字母 + 数字(6-16位)](#✅ 密码必须包含大小写字母 + 数字(6-16位))
- [✅ URL 校验](#✅ URL 校验)
- [🧪 4. Java 中正则使用方式](#🧪 4. Java 中正则使用方式)
-
- [🔍 字符串匹配](#🔍 字符串匹配)
- [🔎 字符串提取](#🔎 字符串提取)

Ⅰ. Stream API
常见的 Java 8 Stream API 可以分成几类:创建、转换、中间操作、终止操作。
- 创建操作:得到一个流对象
- 中间操作:返回的还是一个新的流(lazy,不会真正执行)
- 终止操作:才会触发整个流水线的执行,产生结果(数值、集合、Optional 等)
java
Stream<Integer> s = Stream.of(1, 2, 3, 4)
.filter(x -> x > 2) // 中间操作,返回流
.map(x -> x * 10); // 中间操作,返回流
// 到这里还没执行,s 只是描述了一条"流水线"
List<Integer> list = s.collect(Collectors.toList()); // 终止操作,真正执行
System.out.println(list); // [30, 40]
一、Stream 创建方式
| 方法 | 说明 | 示例 |
|---|---|---|
| Stream.of(T...) | 由一组元素创建 | Stream.of(1,2,3) |
| Arrays.stream(array) | 由数组创建 | Arrays.stream(new int[]{1,2,3}) |
| Collection.stream() | 由集合创建 | list.stream() |
| Collection.parallelStream() | 并行流 | list.parallelStream() |
| Stream.iterate(seed, f) | 无限流(迭代生成) | Stream.iterate(1, n -> n+1) |
| Stream.generate(Supplier) | 无限流(供应生成) | Stream.generate(Math::random) |
二、中间操作(返回新的 Stream,可链式调用)
| 方法 | 说明 | 示例 |
|---|---|---|
| filter(Predicate) | 过滤元素 | stream.filter(x -> x > 10) |
| map(Function) | 映射/转换 | stream.map(String::length) |
| flatMap(Function) | 扁平化映射 | stream.flatMap(s -> Arrays.stream(s.split(","))) |
| distinct() | 去重 | stream.distinct() |
| sorted() | 自然排序 | stream.sorted() |
| sorted(Comparator) | 自定义排序 | stream.sorted((a,b)->b-a) |
| limit(n) | 截取前 n 个 | stream.limit(5) |
| skip(n) | 跳过前 n 个 | stream.skip(3) |
| peek(Consumer) | 调试/查看中间值 | stream.peek(System.out::println) |
三、终止操作(触发流处理,返回具体结果)
- 集合结果 :
collect - 聚合结果 :
reduce、count、min、max - 布尔判断 :
anyMatch、allMatch、noneMatch - 单元素 :
findFirst、findAny - 遍历/副作用 :
forEach
| 方法 | 说明 | 返回值类型 | 示例 |
|---|---|---|---|
| forEach(Consumer) | 遍历元素(无返回) | void | stream.forEach(System.out::println) |
| toArray() | 转数组 | Object[] 或 T[] | stream.toArray() |
| collect(Collector) | 收集结果 | 泛型 R(常见:List、Set、Map) | stream.collect(Collectors.toList()) |
| reduce(BinaryOperator) | 规约(累加、累乘等) | Optional | stream.reduce(Integer::sum) |
| reduce(identity, BinaryOperator) | 带初始值的规约 | T | stream.reduce(0, Integer::sum) |
| count() | 统计数量 | long | stream.count() |
| min(Comparator) | 最小值 | Optional | stream.min(Integer::compare) |
| max(Comparator) | 最大值 | Optional | stream.max(Integer::compare) |
| anyMatch(Predicate) | 是否存在任意满足条件 | boolean | stream.anyMatch(x -> x > 10) |
| allMatch(Predicate) | 是否所有元素满足条件 | boolean | stream.allMatch(x -> x > 0) |
| noneMatch(Predicate) | 是否没有元素满足条件 | boolean | stream.noneMatch(x -> x < 0) |
| findFirst() | 返回第一个元素 | Optional | stream.findFirst() |
| findAny() | 返回任意一个元素(并行流常用) | Optional | stream.findAny() |
Ⅱ. Optional 类
Optional<T> 是一个可能包含值也可能为空的容器对象,它替代了传统的 null 返回,用更安全、明确、链式的方式处理值的存在或缺失。
常用方法如下所示:
| 方法名 | 返回值 | 说明 |
|---|---|---|
| of(T value) | Optional | 创建非空的 Optional,传 null 会抛异常 |
| ofNullable(T value) | Optional | 创建 Optional,允许 null |
| empty() | Optional | 创建一个空的 Optional |
| isPresent() | boolean | 判断是否有值(true/false) |
| ifPresent(Consumer) | void | 如果有值就执行某个操作 |
| get() | T | 获取值,若为空会抛 NoSuchElementException |
| orElse(T other) | T | 若有值则返回,否则返回默认值 (总会执行传入的表达式,无论是否为空) |
| orElseGet(Supplier) | T | 若有值返回,否则调用函数获取默认值 (只有为空才会执行传入的表达式) |
| orElseThrow() | T | 若为空抛异常(默认抛 NoSuchElementException) |
| orElseThrow(Supplier) | T | 若为空抛自定义异常 |
| map(Function) | Optional | 对值做转换操作(包装成新的 Optional) |
| flatMap(Function) | Optional | 链式调用,避免嵌套 Optional |
| filter(Predicate) | Optional | 判断值是否满足条件,不满足则变成 empty |
注意事项:
- ❌ 不要用
get()随意取值,如果值为 null 会直接抛异常。 - ✅ 推荐始终使用
orElse/ifPresent等方法来处理 Optional。
java
// 创建一个optional对象
Optional<String> optionalName = Optional.of("lirendada");
// 1. 是否有值
optionalName.isPresent(); // true
// 2. 如果有值就打印
optionalName.ifPresent(name -> System.out.println("Name: " + name));
// 3. 获取值(不推荐直接用 get)
String name = optionalName.get();
// 4. 如果为空则返回默认值
String value = Optional.ofNullable(null).orElse("默认值"); // "默认值"
// 5. 用 orElseGet 延迟执行
String v = Optional.ofNullable(null).orElseGet(() -> getDefault());
// 6. 为空则抛异常
String error = Optional.ofNullable(null)
.orElseThrow(() -> new IllegalArgumentException("值不能为空"));
// 7. 转换值(map)
Optional<Integer> nameLength = optionalName.map(String::length);
// 8. 链式调用 + 判断
String result = Optional.of("lirendada")
.filter(s -> s.length() > 5)
.map(String::toUpperCase)
.orElse("太短了");
// 输出:LIRENDADA
Ⅲ. 两者结合的一个例子
findFirst() 是 Java Stream 中的一个终止操作(Terminal Operation),作用是:
在过滤或处理后的流中,返回"第一个匹配的元素"(包装在
Optional中)。
如果不用 findFirst() 结束的话,就会得到一个 无限的 Stream 流对象 ,而不是最终的 PrizeEntity 元素。
java
Optional<PrizeEntity> optionalPrizeDTO = prizes.stream()
.filter(y -> y.getId().equals(x.getPrizeId()))
.findFirst();
// 如果 optionalPrizeDTO 不为空,执行该方法
optionalPrizeDTO.ifPresent(y -> {
// 设置详细属性
});
Ⅳ. 正则表达式
正则表达式(Regular Expression)是一种文本模式匹配工具,常用于字符串校验、提取、替换等操作。
- 使用 regex101.com 在线测试正则
🧠 1. 基础元字符(Metacharacters)
| 符号 | 含义 | 示例 | 匹配内容 |
|---|---|---|---|
. |
任意单个字符(除换行) | a.b |
acb, a9b |
^ |
匹配字符串开始 | ^abc |
abc123 ✅,xabc ❌ |
$ |
匹配字符串结束 | abc$ |
123abc ✅,abc123 ❌ |
* |
重复 0 次或多次 | ab*c |
ac, abc, abbbc |
+ |
重复 1 次或多次 | ab+c |
abc, abbbc |
? |
重复 0 次或 1 次(可选) | ab?c |
ac, abc |
[] |
匹配一个字符 | [abc] |
a, b, c |
[^] |
匹配不在集合内的字符 | [^0-9] |
非数字 |
{n} |
重复 n 次 | a{3} |
aaa |
{n,} |
至少重复 n 次 | a{2,} |
aa, aaa |
{n,m} |
重复 n~m 次 | a{2,4} |
aa, aaa, aaaa |
| ` | ` | 或 | `abc |
() |
分组 | (abc)+ |
匹配多个 abc |
📚 2. 常用转义字符
| 符号 | 含义 | 示例 | 匹配内容 |
|---|---|---|---|
| \d | 数字 [0-9] |
\d{3} |
123 |
| \D | 非数字 | \D+ |
abc |
| \w | 单词字符 [a-zA-Z0-9_] |
\w+ |
abc_123 |
| \W | 非单词字符 | \W+ |
#@! |
| \s | 空白字符(空格、Tab、换行) | \s+ |
" "、\t、\n |
| \S | 非空白字符 | \S+ |
abc123 |
| \b | 单词边界 | \bword\b |
匹配独立单词 word |
| \B | 非单词边界 | \Bword\B |
中间位置 xwordx |
🔐 3. 常用校验正则(可直接用于 Java)
✅ 邮箱
Plain
^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$
✅ 手机号(中国大陆)
Plain
^1[3-9]\d{9}$
✅ 身份证(大陆 18位)
Plain
^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$
✅ 密码强度(6-12位,字母或数字)
Plain
^[A-Za-z0-9]{6,12}$
✅ 密码必须包含大小写字母 + 数字(6-16位)
Plain
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d]{6,16}$
✅ URL 校验
Plain
^(https?://)?([a-zA-Z0-9.-]+)(:[0-9]{1,5})?(/.*)?$
🧪 4. Java 中正则使用方式
🔍 字符串匹配
java
String regex = "^1[3-9]\\d{9}$";
boolean isValid = Pattern.matches(regex, "13812345678");
🔎 字符串提取
java
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher("abc123xyz456");
while (matcher.find()) {
System.out.println(matcher.group()); // 输出 123 和 456
}
