选项工具-Opt
# 选项工具-Opt
# 模块介绍
Opt是Hutool对JDK Optional的扩展实现,提供了更多实用功能。它复制了JDK 16中的Optional特性,并进行了调整和新增,比JDK 8中的Optional更加灵活和强大。
# 为什么封装此模块
- 扩展JDK Optional功能:在JDK 8 Optional基础上增加了更多实用方法
- 支持异常处理:提供了ofTry方法,支持从可能抛出异常的操作中创建Opt
- 更丰富的空值判断:支持空白字符串、空集合等多种空值情况的判断
- 链式调用优化:提供了更流畅的API设计,支持多个操作链
- 兼容性更好:在不同JDK版本上提供一致的功能
- 更实用的get方法:getOrNull方法返回null而非抛出异常,符合实际开发需求
# JDK问题解决
JDK标准Optional存在以下问题:
- JDK 8版本功能有限,缺少一些实用方法
- get()方法在值为空时抛出异常,不够友好
- 不支持从可能抛出异常的操作中创建
- 缺少对空白字符串、空集合等特殊空值情况的处理
- 多个操作需要嵌套调用,不够流畅
Opt工具通过扩展和优化,解决了这些问题,提供了更易用、更强大的Optional实现。
# 相关JDK模块
java.util.Optional:JDK标准Optional类java.util.function:函数式接口支持java.util.stream:流操作支持
# API文档
# 创建Opt对象
# empty方法
功能:返回一个空的Opt对象。
public static <T> Opt<T> empty()
示例:
Opt<String> emptyOpt = Opt.empty();
# of方法
功能:返回一个包裹里元素不可能为空的Opt。如果传入的元素为空,抛出NPE。
public static <T> Opt<T> of(final T value)
示例:
Opt<String> opt1 = Opt.of("Hello"); // 正常创建
// Opt<String> opt2 = Opt.of(null); // 抛出NullPointerException
# ofNullable方法
功能:返回一个包裹里元素可能为空的Opt。
public static <T> Opt<T> ofNullable(final T value)
示例:
Opt<String> opt1 = Opt.ofNullable("Hello"); // 包裹非空值
Opt<String> opt2 = Opt.ofNullable(null); // 包裹空值
# ofBlankAble方法
功能:返回一个包裹里元素可能为空的Opt,额外判断了空字符串的情况。
public static <T extends CharSequence> Opt<T> ofBlankAble(final T value)
示例:
Opt<String> opt1 = Opt.ofBlankAble("Hello"); // 正常创建
Opt<String> opt2 = Opt.ofBlankAble(""); // 空字符串,返回empty
Opt<String> opt3 = Opt.ofBlankAble(" "); // 空白字符串,返回empty
# ofEmptyAble方法
功能:返回一个包裹里集合可能为空的Opt,额外判断了集合内元素为空的情况。
public static <T, R extends Collection<T>> Opt<R> ofEmptyAble(final R value)
示例:
List<String> list1 = Arrays.asList("a", "b");
Opt<List<String>> opt1 = Opt.ofEmptyAble(list1); // 正常创建
List<String> list2 = new ArrayList<>();
Opt<List<String>> opt2 = Opt.ofEmptyAble(list2); // 空集合,返回empty
# ofTry方法
功能:从可能抛出异常的操作中创建Opt。
public static <T> Opt<T> ofTry(final SerSupplier<T> supplier)
示例:
// 正常操作
Opt<Integer> opt1 = Opt.ofTry(() -> 1 + 2); // 结果为3
// 可能抛出异常的操作
Opt<Integer> opt2 = Opt.ofTry(() -> 1 / 0); // 捕获异常,创建包含异常信息的Opt
# 值获取方法
# getOrNull方法
功能:返回包裹里的元素,取不到则为null,与JDK Optional的get()方法不同,本方法不会抛出异常。
public T getOrNull()
示例:
Opt<String> opt1 = Opt.ofNullable("Hello");
String value1 = opt1.getOrNull(); // "Hello"
Opt<String> opt2 = Opt.ofNullable(null);
String value2 = opt2.getOrNull(); // null
# getOrThrow方法
功能:返回包裹里的元素,取不到则抛出NoSuchElementException。
public T getOrThrow() throws NoSuchElementException
示例:
Opt<String> opt1 = Opt.ofNullable("Hello");
String value1 = opt1.getOrThrow(); // "Hello"
Opt<String> opt2 = Opt.ofNullable(null);
// String value2 = opt2.getOrThrow(); // 抛出NoSuchElementException
# 状态检查方法
# isPresent/isEmpty方法
功能:判断包裹里元素的值是否存在或不存在。
public boolean isPresent()
public boolean isEmpty()
示例:
Opt<String> opt1 = Opt.ofNullable("Hello");
boolean isPresent1 = opt1.isPresent(); // true
boolean isEmpty1 = opt1.isEmpty(); // false
Opt<String> opt2 = Opt.ofNullable(null);
boolean isPresent2 = opt2.isPresent(); // false
boolean isEmpty2 = opt2.isEmpty(); // true
# 条件执行方法
# ifPresent方法
功能:如果包裹里的值存在,就执行传入的操作。
public Opt<T> ifPresent(final SerConsumer<? super T> action)
示例:
Opt.ofNullable("Hello").ifPresent(System.out::println); // 输出 "Hello"
Opt.ofNullable(null).ifPresent(System.out::println); // 不执行操作
# ifPresents方法
功能:如果包裹里元素的值存在,就执行对应的操作集。
@SafeVarargs
public final Opt<T> ifPresents(final SerConsumer<T>... actions)
示例:
Opt.ofNullable("Hello")
.ifPresents(
s -> Console.log("First: " + s),
s -> Console.log("Second: " + s.toUpperCase())
);
// 输出:
// First: Hello
// Second: HELLO
# ifFail方法
功能:如果包裹内容失败了,则执行传入的操作。
public Opt<T> ifFail(final Consumer<? super Throwable> action)
示例:
Opt.ofTry(() -> 1 / 0)
.ifFail(e -> Console.log("Error: " + e.getMessage())); // 输出异常信息
# 过滤和转换方法
# filter方法
功能:根据条件过滤Opt,如果满足条件则返回本身,否则返回空Opt。
public Opt<T> filter(final SerPredicate<? super T> predicate)
示例:
Opt<Integer> opt1 = Opt.ofNullable(10)
.filter(i -> i > 5); // 满足条件,返回原Opt
Opt<Integer> opt2 = Opt.ofNullable(3)
.filter(i -> i > 5); // 不满足条件,返回empty
# map方法
功能:如果包裹里的值存在,就执行传入的操作并返回一个包裹了该操作返回值的Opt。
public <U> Opt<U> map(final SerFunction<? super T, ? extends U> mapper)
示例:
Opt<String> opt1 = Opt.ofNullable("Hello")
.map(String::toUpperCase); // 返回 Opt.ofNullable("HELLO")
Opt<String> opt2 = Opt.ofNullable(null)
.map(String::toUpperCase); // 返回 empty
# flattedMap方法
功能:如果包裹里的值存在,就执行传入的操作并返回该操作返回值,与map方法的区别是传入的操作返回值必须为Optional。
public <U> Opt<U> flattedMap(final SerFunction<? super T, ? extends Optional<? extends U>> mapper)
示例:
Opt<String> opt = Opt.ofNullable("Hello")
.flattedMap(s -> Optional.of(s.toUpperCase())); // 返回 Opt.ofNullable("HELLO")
# stream方法
功能:如果包裹里元素的值存在,就返回一个包含该元素的Stream,否则返回一个空Stream。
public Stream<T> stream()
示例:
Opt<String> opt1 = Opt.ofNullable("Hello");
Stream<String> stream1 = opt1.stream(); // 包含一个元素的Stream
Opt<String> opt2 = Opt.ofNullable(null);
Stream<String> stream2 = opt2.stream(); // 空Stream
# 默认值处理方法
# orElse方法
功能:如果包裹里元素的值存在,则返回该值,否则返回传入的other。
public T orElse(final T other)
示例:
String value1 = Opt.ofNullable("Hello").orElse("Default"); // "Hello"
String value2 = Opt.ofNullable(null).orElse("Default"); // "Default"
# orElseGet方法
功能:如果包裹里元素的值存在,则返回该值,否则返回传入的操作执行后的返回值。
public T orElseGet(final SerSupplier<? extends T> supplier)
示例:
String value1 = Opt.ofNullable("Hello")
.orElseGet(() -> "Generated Default"); // "Hello"
String value2 = Opt.ofNullable(null)
.orElseGet(() -> "Generated Default"); // "Generated Default"
# orElseThrow方法
功能:如果包裹里的值存在,则返回该值,否则抛出指定异常。
public <X extends Throwable> T orElseThrow(final SerSupplier<? extends X> exceptionSupplier)
示例:
String value1 = Opt.ofNullable("Hello")
.orElseThrow(() -> new IllegalArgumentException("Value is null")); // "Hello"
// String value2 = Opt.ofNullable(null)
// .orElseThrow(() -> new IllegalArgumentException("Value is null")); // 抛出异常
# 完整示例
# 链式调用示例
// 链式调用示例
String result = Opt.ofNullable(" Hutool ")
.map(String::trim) // 去除空格
.filter(s -> s.length() > 0) // 过滤非空字符串
.map(String::toUpperCase) // 转换为大写
.orElse("DEFAULT"); // 默认值
Console.log(result); // 输出 "HUTOOL"
# 异常处理示例
// 异常处理示例
Opt.ofTry(() -> {
int a = 10;
int b = 0;
return a / b; // 会抛出ArithmeticException
})
.ifFail(e -> Console.log("Calculation error: " + e.getMessage()))
.exceptionOrElse(-1) // 异常时返回默认值
.ifPresent(result -> Console.log("Result: " + result));
# 实际应用场景示例
// 实际应用场景:用户信息查询
public User getUserById(String userId) {
return Opt.ofNullable(userId)
.filter(id -> id.length() > 0)
.map(this::queryUserFromDatabase) // 从数据库查询用户
.orElseGet(() -> {
// 如果查询不到,返回默认用户
User defaultUser = new User();
defaultUser.setId("default");
defaultUser.setName("Guest");
return defaultUser;
});
}
// 数据库查询方法(模拟)
private User queryUserFromDatabase(String userId) {
// 模拟数据库查询
if ("123".equals(userId)) {
User user = new User();
user.setId(userId);
user.setName("张三");
return user;
}
return null; // 查询不到返回null
}
// 使用示例
User user1 = getUserById("123"); // 返回张三
User user2 = getUserById("456"); // 返回默认用户
User user3 = getUserById(null); // 返回默认用户
# 与Stream结合示例
// 与Stream结合示例
List<String> userIds = Arrays.asList("123", "456", "", null, "789");
List<User> users = userIds.stream()
.map(Opt::ofNullable) // 将每个userId转换为Opt
.filter(Opt::isPresent) // 过滤空值
.map(opt -> opt.getOrNull()) // 获取值
.filter(id -> id.length() > 0) // 过滤空字符串
.map(this::queryUserFromDatabase) // 查询用户
.filter(Objects::nonNull) // 过滤查询不到的用户
.collect(Collectors.toList());
Console.log("查询到的用户数:" + users.size());
# 应用场景
- 避免空指针异常:使用Opt包裹可能为null的值,避免直接调用方法导致的NullPointerException
- 简化条件判断:使用链式调用代替繁琐的if-else判断
- 异常安全操作:通过ofTry方法安全地执行可能抛出异常的操作
- 空值统一处理:对空白字符串、空集合等特殊空值情况进行统一处理
- 函数式编程:结合函数式接口实现更流畅的代码编写
- API设计:在方法返回值中使用Opt,明确表示可能返回空值
- 流操作集成:通过stream方法方便地与Stream API集成
Opt工具提供了丰富的功能和灵活的API,能够显著提高代码的可读性和健壮性,适合各种需要处理可能为null值的场景。