【JavaSE】Stream API && Optiona类 && 正则表达式

文章目录

  • [Ⅰ. Stream API](#Ⅰ. Stream API)
  • [Ⅱ. 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
  • 聚合结果reducecountminmax
  • 布尔判断anyMatchallMatchnoneMatch
  • 单元素findFirstfindAny
  • 遍历/副作用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)是一种文本模式匹配工具,常用于字符串校验、提取、替换等操作。

🧠 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
}
相关推荐
Patrick在香港13 小时前
Python正则表达式实战:解析和验证香港身份证、车牌、电话格式
开发语言·python·正则表达式
吴声子夜歌2 天前
正则指引——Ruby
开发语言·正则表达式·ruby
吴声子夜歌3 天前
正则指引——Golang
开发语言·golang·正则表达式
吴声子夜歌4 天前
正则指引——PHP
开发语言·正则表达式·php
吴声子夜歌5 天前
正则指引——断言
正则表达式
吴声子夜歌6 天前
正则指引——匹配原理
java·正则表达式
吴声子夜歌7 天前
正则表达式——环视
开发语言·正则表达式
吴声子夜歌7 天前
正则表达式——边界
正则表达式
营养充电站8 天前
C++23 新特性在 CLion 中的实战体验
macos·docker·jupyter·正则表达式