文章目录
- Ⅰ. Stream API
- 一、Stream 创建方式
- 二、中间操作(返回新的 Stream,可链式调用)
- 三、终止操作(触发流处理,返回具体结果)
- Ⅱ. Optional 类
- Ⅲ. 两者结合的一个例子
- Ⅳ. 正则表达式
- 🧠 1. 基础元字符(Metacharacters)
- 📚 2. 常用转义字符
- 🔐 3. 常用校验正则(可直接用于 Java)
- ✅ 邮箱
- ✅ 手机号(中国大陆)
- ✅ 身份证(大陆 18位)
- ✅ 密码强度(6-12位,字母或数字)
- ✅ 密码必须包含大小写字母 + 数字(6-16位)
- ✅ URL 校验
- 🧪 4. Java 中正则使用方式
- 🔍 字符串匹配
- 🔎 字符串提取
Ⅰ. Stream API
常见的Java 8 Stream API可以分成几类:创建、转换、中间操作、终止操作。
- 创建操作:得到一个流对象
- 中间操作:返回的还是一个新的流(lazy,不会真正执行)
- 终止操作:才会触发整个流水线的执行,产生结果(数值、集合、Optional 等)
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。
// 创建一个optional对象Optional<String>optionalName=Optional.of("lirendada");// 1. 是否有值optionalName.isPresent();// true// 2. 如果有值就打印optionalName.ifPresent(name->System.out.println("Name: "+name));// 3. 获取值(不推荐直接用 get)Stringname=optionalName.get();// 4. 如果为空则返回默认值Stringvalue=Optional.ofNullable(null).orElse("默认值");// "默认值"// 5. 用 orElseGet 延迟执行Stringv=Optional.ofNullable(null).orElseGet(()->getDefault());// 6. 为空则抛异常Stringerror=Optional.ofNullable(null).orElseThrow(()->newIllegalArgumentException("值不能为空"));// 7. 转换值(map)Optional<Integer>nameLength=optionalName.map(String::length);// 8. 链式调用 + 判断Stringresult=Optional.of("lirendada").filter(s->s.length()>5).map(String::toUpperCase).orElse("太短了");// 输出:LIRENDADAⅢ. 两者结合的一个例子
findFirst()是 Java Stream 中的一个终止操作(Terminal Operation),作用是:
在过滤或处理后的流中,返回“第一个匹配的元素”(包装在
Optional中)。
如果不用findFirst()结束的话,就会得到一个无限的 Stream 流对象,而不是最终的PrizeEntity元素。
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)
✅ 邮箱
^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$✅ 手机号(中国大陆)
^1[3-9]\d{9}$✅ 身份证(大陆 18位)
^[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位,字母或数字)
^[A-Za-z0-9]{6,12}$✅ 密码必须包含大小写字母 + 数字(6-16位)
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d]{6,16}$✅ URL 校验
^(https?://)?([a-zA-Z0-9.-]+)(:[0-9]{1,5})?(/.*)?$🧪 4. Java 中正则使用方式
🔍 字符串匹配
Stringregex="^1[3-9]\\d{9}$";booleanisValid=Pattern.matches(regex,"13812345678");🔎 字符串提取
Patternpattern=Pattern.compile("\\d+");Matchermatcher=pattern.matcher("abc123xyz456");while(matcher.find()){System.out.println(matcher.group());// 输出 123 和 456}