🚀 feat(新增): Optional使用

This commit is contained in:
bunny 2024-07-31 10:21:27 +08:00
parent d5784f5337
commit f7e2150735
1 changed files with 252 additions and 0 deletions

View File

@ -0,0 +1,252 @@
package cn.bunny.stream;
import org.junit.jupiter.api.Test;
import java.util.Optional;
public class OptionalTest {
// 提供默认值以确保不会返回 null
// 适用于默认情况下的备选值或简单计算结果
@Test
void orElseTest() {
// 如果 optionalName 为空返回 "Unknown"
Optional<String> optionalName = Optional.empty();
String result = optionalName.orElse("Unknown");
System.out.println("Name: " + result); // 输出 Name: Unknown
// 如果 optionalNumber 不为空返回其值否则返回默认值 0
Optional<Integer> optionalNumber = Optional.of(10);
int number = optionalNumber.orElse(0);
System.out.println("Number: " + number); // 输出 Number: 10
}
// 当生成默认值可能会带来额外开销时可以使用 orElseGet 来提高性能
// 允许生成复杂的默认值或者依赖于条件的值
@Test
void orElseGetTest() {
// 如果 optionalName 为空通过 Supplier 生成默认值
Optional<String> optionalName = Optional.empty();
String result = optionalName.orElse("Name not provided");
System.out.println("Name: " + result); // 输出 Name: Name not provided
// 如果 optionalScore 为空通过 Supplier 生成默认值
Optional<Double> optionalScore = Optional.ofNullable(null);
double score = optionalScore.orElseGet(() -> Math.random() * 100);
System.out.println("Score: " + score); // 输出 Score: 随机生成的分数值
}
// Optional 为空时抛出异常以确保程序不会继续执行下去
// 用于强制要求 Optional 中必须包含值的场景
@Test
void orElseThrowTest() {
// 如果 optionalName 为空抛出 IllegalArgumentException 异常
Optional<String> optionalName = Optional.empty();
try {
String result = optionalName.orElseThrow(() -> new IllegalArgumentException("Name not provided"));
System.out.println("Name: " + result);
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage()); // 输出 Name not provided
}
// 如果 optionalNumber 为空抛出 NullPointerException 异常
Optional<Integer> optionalNumber = Optional.ofNullable(null);
try {
int number = optionalNumber.orElseThrow(NullPointerException::new);
System.out.println("Number: " + number);
} catch (NullPointerException e) {
System.out.println("Caught exception: " + e.getMessage()); // 输出 Caught exception: null
}
}
// 条件判断和流程控制 可以根据 Optional 是否包含值来决定程序的执行路径
// 避免空指针异常 在对可能为 null 的值进行操作之前先使用 isPresent() 来检查是否存在值以避免空指针异常的发生
// 默认值处理 结合 isPresent() orElse orElseGet 方法可以根据 Optional 是否包含值来决定返回默认值或进行其他处理
@Test
void isPresentTest() {
// 检查 optionalName 是否包含值
Optional<String> optionalName = Optional.of("Alice");
if (optionalName.isPresent()) {
System.out.println("Name is present: " + optionalName.get()); // 输出 Name is present: Alice
} else {
System.out.println("Name not found");
}
// 使用 isPresent() 来避免空指针异常
Optional<Integer> optionalNumber = Optional.empty();
if (optionalNumber.isPresent()) {
int number = optionalNumber.get(); // 这里不会执行因为 optionalNumber 为空
System.out.println("Number: " + number);
} else {
System.out.println("Number not found");
}
// 结合 orElseGet 使用 isPresent() 来提供默认值
String defaultName = "Default";
Optional<String> optionalName2 = Optional.empty();
String result = optionalName2.isPresent() ? optionalName2.get() : defaultName;
System.out.println("Name: " + result); // 输出 Name: Default
}
// 值转换 Optional 中的值进行转换或者计算
// 链式调用 可以与其他方法如 filterflatMap 一起使用实现复杂的值处理逻辑
@Test
void mapTest() {
Optional<String> optionalName = Optional.of("Alice");
// 将字符串转换为大写
Optional<String> upperCaseName = optionalName.map(name -> name.toUpperCase());
System.out.println("Upper case name: " + upperCaseName.get()); // 输出 Upper case name: ALICE
Optional<Integer> optionalNumber = Optional.of(10);
// 对数字进行加倍
Optional<Integer> doubledNumber = optionalNumber.map(num -> num * 2);
System.out.println("Doubled number: " + doubledNumber.get()); // 输出 Doubled number: 20
Optional<String> optionalEmpty = Optional.empty();
// 对空 Optional 进行映射
Optional<String> mappedEmpty = optionalEmpty.map(value -> value.toUpperCase());
System.out.println("Mapped empty: " + mappedEmpty.isPresent()); // 输出 Mapped empty: false
}
// 条件过滤 根据指定的条件过滤掉不符合要求的值
// 优化流程 在确定 Optional 包含有效值之前可以使用 filter 进行必要的条件检查
@Test
void filterTest() {
// 过滤出长度大于3的名字
Optional<String> optionalName = Optional.of("Bob");
Optional<String> filteredName = optionalName.filter(name -> name.length() > 3);
System.out.println("Filtered name: " + filteredName.isPresent()); // 输出 Filtered name: false
// 过滤出大于10的数字
Optional<Integer> optionalNumber = Optional.of(15);
Optional<Integer> filteredNumber = optionalNumber.filter(num -> num > 10);
System.out.println("Filtered number: " + filteredNumber.get()); // 输出 Filtered number: 15
// 对空 Optional 进行过滤
Optional<Integer> optionalEmpty = Optional.empty();
Optional<Integer> filteredEmpty = optionalEmpty.filter(value -> value > 0);
System.out.println("Filtered empty: " + filteredEmpty.isPresent()); // 输出 Filtered empty: false
}
// 备选方案 在原始 Optional 为空时提供一个备选的 Optional 对象
// 链式调用 可以与 orElse, orElseGet 等方法结合使用实现更复杂的值获取逻辑
@Test
void orTest() {
// 如果 optionalName 为空则返回 backupName
Optional<String> optionalName = Optional.empty();
Optional<String> backupName = Optional.of("Backup Name");
Optional<String> result = optionalName.or(() -> backupName);
System.out.println("Result: " + result.get()); // 输出 Result: Backup Name
// 如果 optionalNumber 不为空则返回 optionalNumber否则返回 backupNumber
Optional<Integer> optionalNumber = Optional.of(5);
Optional<Integer> backupNumber = Optional.empty();
Optional<Integer> resultNumber = optionalNumber.or(() -> backupNumber);
System.out.println("Result number: " + resultNumber.get()); // 输出 Result number: 5
}
// 获取值 当确定 Optional 包含值时直接获取该值
// 注意事项 使用 get 方法时必须先通过 isPresent 或者其他条件确保 Optional 包含值避免抛出异常
@Test
void getTest() {
Optional<String> optionalName = Optional.of("Alice");
// 直接获取 Optional 中的值
String name = optionalName.get();
System.out.println("Name: " + name); // 输出 Name: Alice
Optional<String> optionalEmpty = Optional.empty();
// 尝试从空的 Optional 中获取值会抛出 NoSuchElementException 异常
// String emptyName = optionalEmpty.get();
// System.out.println("Empty Name: " + emptyName); // 抛出 NoSuchElementException
}
// 处理空值情况 提供一个异常供给型函数 Optional 为空时抛出指定异常
// 自定义异常信息 可以通过自定义的异常类型和消息来更好地描述空值情况
@Test
void orElseThrowTest2() {
Optional<String> optionalName = Optional.empty();
// 如果 optionalName 为空则抛出自定义的异常
String name = optionalName.orElseThrow(() -> new IllegalStateException("Name is not present"));
// 输出异常信息Exception in thread "main" java.lang.IllegalStateException: Name is not present
}
// 判断空值 更直观地判断 Optional 是否为空
// 条件逻辑 可以与其他方法结合使用优化条件判断逻辑
@Test
void isEmptyTest() {
Optional<String> optionalName = Optional.of("Bob");
Optional<String> optionalEmpty = Optional.empty();
// 检查 optionalName 是否为空
boolean namePresent = !optionalName.isEmpty();
System.out.println("Name present: " + namePresent); // 输出 Name present: true
// 检查 optionalEmpty 是否为空
boolean emptyPresent = !optionalEmpty.isEmpty();
System.out.println("Empty present: " + emptyPresent); // 输出 Empty present: false
}
// 非空值的创建 当确定值不为 null 可以使用 of 创建对应的 Optional 对象
// 避免空指针异常 在确定值不为 null 的情况下使用 of 可以直接创建 Optional 对象避免后续空指针异常
@Test
void ofTest() {
String name = "Alice";
// 创建包含非 null 值的 Optional 对象
Optional<String> optionalName = Optional.of(name);
System.out.println("Name: " + optionalName.get()); // 输出 Name: Alice
String nullName = null;
// 尝试使用 null 创建 Optional 对象会抛出 NullPointerException
// Optional<String> optionalNull = Optional.of(nullName);
// System.out.println("Null Name: " + optionalNull.get()); // 抛出 NullPointerException
}
// 可能为空的值的创建 当值可能为 null 可以使用 ofNullable 创建对应的 Optional 对象
// 安全地处理可能为 null 的情况 可以避免直接操作可能为 null 的值提高代码的健壮性
@Test
void ofNullableTest() {
String name = "Bob";
String nullName = null;
// 创建包含非 null 值的 Optional 对象
Optional<String> optionalName = Optional.ofNullable(name);
System.out.println("Name: " + optionalName.orElse("Default Name")); // 输出 Name: Bob
// 创建可能为空的 Optional 对象
Optional<String> optionalNull = Optional.ofNullable(nullName);
System.out.println("Null Name: " + optionalNull.orElse("Default Name")); // 输出 Null Name: Default Name
}
// 表示缺失值 可以用于明确指示某个值不存在的情况
// 结合其他方法使用 可以与 orElse, orElseGet, orElseThrow 等方法结合使用提供默认值或者处理逻辑
@Test
void emptyTest() {
Optional<String> emptyOptional = Optional.empty();
// 使用 empty 创建的 Optional 对象没有值
System.out.println("Empty Optional: " + emptyOptional.isPresent()); // 输出 Empty Optional: false
}
// 扁平化映射 用于处理嵌套的 Optional 结构将嵌套的 Optional 展开为单层结构
// 链式调用 可以与 map 结合使用进行复杂的值转换和处理
@Test
void flatMapTest() {
Optional<String> optionalName = Optional.of("Alice");
Optional<String> optionalEmpty = Optional.empty();
// 使用 flatMap Optional<String> 转换为 Optional<Integer>
Optional<Integer> nameLengthOptional = optionalName.flatMap(name -> Optional.of(name.length()));
System.out.println("Name length: " + nameLengthOptional.get()); // 输出 Name length: 5
// 如果 Optional 是空的 flatMap 不执行映射
Optional<Integer> emptyLengthOptional = optionalEmpty.flatMap(value -> Optional.of(value.length()));
System.out.println("Empty length: " + emptyLengthOptional.isPresent()); // 输出 Empty length: false
}
}