mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
add OptionalBean
This commit is contained in:
parent
02c97eedde
commit
2b89f3fca8
@ -6,6 +6,7 @@
|
|||||||
# 5.4.7 (2020-10-23)
|
# 5.4.7 (2020-10-23)
|
||||||
|
|
||||||
### 新特性
|
### 新特性
|
||||||
|
* 【core 】 增加OptionalBean(pr#1182@Github)
|
||||||
### Bug修复
|
### Bug修复
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -1,130 +1,152 @@
|
|||||||
package cn.hutool.core.bean;
|
package cn.hutool.core.bean;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* optional 判空
|
* optional对象判空,参考:https://mp.weixin.qq.com/s/0c8iC0OTtx5LqPkhvkK0tw<br>
|
||||||
* @param <T>
|
* from:https://github.com/looly/hutool/pull/1182
|
||||||
|
*
|
||||||
|
* @param <T> Bean类型
|
||||||
* @author totalo
|
* @author totalo
|
||||||
* @since 5.4.7
|
* @since 5.4.7
|
||||||
* @see https://mp.weixin.qq.com/s/0c8iC0OTtx5LqPkhvkK0tw
|
|
||||||
*/
|
*/
|
||||||
public final class OptionalBean<T> {
|
public final class OptionalBean<T> {
|
||||||
|
|
||||||
private static final OptionalBean<?> EMPTY = new OptionalBean<>();
|
private static final OptionalBean<?> EMPTY = new OptionalBean<>();
|
||||||
|
|
||||||
private final T value;
|
/**
|
||||||
|
* 空值常量
|
||||||
|
*
|
||||||
|
* @param <T> 对象类型
|
||||||
|
* @return 空
|
||||||
|
*/
|
||||||
|
public static <T> OptionalBean<T> empty() {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
OptionalBean<T> none = (OptionalBean<T>) EMPTY;
|
||||||
|
return none;
|
||||||
|
}
|
||||||
|
|
||||||
private OptionalBean() {
|
private final T value;
|
||||||
this.value = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 空值会抛出空指针
|
* 构造
|
||||||
* @param value
|
*/
|
||||||
*/
|
private OptionalBean() {
|
||||||
private OptionalBean(T value) {
|
this.value = null;
|
||||||
this.value = Objects.requireNonNull(value);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 包装一个不能为空的 bean
|
* 空值会抛出空指针
|
||||||
* @param value
|
*
|
||||||
* @param <T>
|
* @param value Bean值
|
||||||
* @return
|
*/
|
||||||
*/
|
private OptionalBean(T value) {
|
||||||
public static <T> OptionalBean<T> of(T value) {
|
this.value = Objects.requireNonNull(value);
|
||||||
return new OptionalBean<>(value);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 包装一个可能为空的 bean
|
* 包装一个不能为空的 bean
|
||||||
* @param value
|
*
|
||||||
* @param <T>
|
* @param <T> bean类型
|
||||||
* @return
|
* @param value Bean值
|
||||||
*/
|
* @return OptionalBean
|
||||||
public static <T> OptionalBean<T> ofNullable(T value) {
|
*/
|
||||||
return value == null ? empty() : of(value);
|
public static <T> OptionalBean<T> of(T value) {
|
||||||
}
|
return new OptionalBean<>(value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取出具体的值
|
* 包装一个可能为空的 bean
|
||||||
* @return
|
*
|
||||||
*/
|
* @param value Bean值
|
||||||
public T get() {
|
* @param <T> bean类型
|
||||||
return Objects.isNull(value) ? null : value;
|
* @return OptionalBean
|
||||||
}
|
*/
|
||||||
|
public static <T> OptionalBean<T> ofNullable(T value) {
|
||||||
|
return value == null ? empty() : of(value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取出一个可能为空的对象
|
* 取出具体的值
|
||||||
* @param fn
|
*
|
||||||
* @param <R>
|
* @return bean值
|
||||||
* @return
|
*/
|
||||||
*/
|
public T get() {
|
||||||
public <R> OptionalBean<R> getBean(Function<? super T, ? extends R> fn) {
|
return value;
|
||||||
return Objects.isNull(value) ? OptionalBean.empty() : OptionalBean.ofNullable(fn.apply(value));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 如果目标值为空 获取一个默认值
|
* 取出一个可能为空的对象
|
||||||
* @param other
|
*
|
||||||
* @return
|
* @param <R> 对象类型
|
||||||
*/
|
* @param fn 从已有bean中获取新bean字段的函数
|
||||||
|
* @return 新的bean
|
||||||
|
*/
|
||||||
|
public <R> OptionalBean<R> getBean(Function<? super T, ? extends R> fn) {
|
||||||
|
return Objects.isNull(value) ? OptionalBean.empty() : OptionalBean.ofNullable(fn.apply(value));
|
||||||
|
}
|
||||||
|
|
||||||
public T orElse(T other) {
|
/**
|
||||||
return value != null ? value : other;
|
* 如果目标值为空 获取一个默认值
|
||||||
}
|
*
|
||||||
|
* @param other 默认值
|
||||||
|
* @return 空返回默认值,否则返回原值
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
public T orElse(T other) {
|
||||||
* 如果目标值为空 通过lambda表达式获取一个值
|
return ObjectUtil.defaultIfNull(this.value, other);
|
||||||
* @param other
|
}
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public T orElseGet(Supplier<? extends T> other) {
|
|
||||||
return value != null ? value : other.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 如果目标值为空 抛出一个异常
|
* 如果目标值为空 通过lambda表达式获取一个值
|
||||||
* @param exceptionSupplier
|
*
|
||||||
* @param <X>
|
* @param other 默认值函数
|
||||||
* @return
|
* @return 空返回默认值函数获得的值,否则返回原值
|
||||||
* @throws X
|
*/
|
||||||
*/
|
public T orElseGet(Supplier<? extends T> other) {
|
||||||
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
|
return null != value ? value : other.get();
|
||||||
if (value != null) {
|
}
|
||||||
return value;
|
|
||||||
} else {
|
|
||||||
throw exceptionSupplier.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isPresent() {
|
/**
|
||||||
return value != null;
|
* 如果目标值为空 抛出一个异常
|
||||||
}
|
*
|
||||||
|
* @param exceptionSupplier 抛出的异常
|
||||||
|
* @param <X> 异常类型
|
||||||
|
* @return 非空值
|
||||||
|
* @throws X 对象为空时抛出的异常
|
||||||
|
*/
|
||||||
|
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
|
||||||
|
return Assert.notNull(this.value, exceptionSupplier);
|
||||||
|
}
|
||||||
|
|
||||||
public void ifPresent(Consumer<? super T> consumer) {
|
/**
|
||||||
if (value != null) {
|
* 检查值是否为空
|
||||||
consumer.accept(value);
|
*
|
||||||
}
|
* @return 是否为空
|
||||||
}
|
*/
|
||||||
|
public boolean isPresent() {
|
||||||
|
return null != this.value;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public int hashCode() {
|
* 如果值非空,则使用指定函数处理值
|
||||||
return Objects.hashCode(value);
|
*
|
||||||
}
|
* @param consumer 处理非空对象的函数
|
||||||
|
*/
|
||||||
|
public void ifPresent(Consumer<? super T> consumer) {
|
||||||
|
if (value != null) {
|
||||||
|
consumer.accept(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* 空值常量
|
public int hashCode() {
|
||||||
* @param <T>
|
return Objects.hashCode(value);
|
||||||
* @return
|
}
|
||||||
*/
|
|
||||||
public static <T> OptionalBean<T> empty() {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
OptionalBean<T> none = (OptionalBean<T>) EMPTY;
|
|
||||||
return none;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -6,44 +6,45 @@ import org.junit.Test;
|
|||||||
|
|
||||||
public class OptionalBeanTest {
|
public class OptionalBeanTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void OptionalBeanTest() {
|
public void optionalBeanTest() {
|
||||||
User user = new User();
|
User user = new User();
|
||||||
user.setName("hello");
|
user.setName("hello");
|
||||||
String value1 = OptionalBean.ofNullable(user)
|
String value1 = OptionalBean.ofNullable(user)
|
||||||
.getBean(User::getSchool)
|
.getBean(User::getSchool)
|
||||||
.getBean(User.School::getAddress).get();
|
.getBean(User.School::getAddress).get();
|
||||||
Assert.assertEquals(value1, null);
|
Assert.assertNull(value1);
|
||||||
|
|
||||||
boolean present = OptionalBean.ofNullable(user)
|
boolean present = OptionalBean.ofNullable(user)
|
||||||
.getBean(User::getSchool)
|
.getBean(User::getSchool)
|
||||||
.getBean(User.School::getAddress).isPresent();
|
.getBean(User.School::getAddress).isPresent();
|
||||||
Assert.assertFalse(present);
|
Assert.assertFalse(present);
|
||||||
|
|
||||||
String value2 = OptionalBean.ofNullable(user)
|
String value2 = OptionalBean.ofNullable(user)
|
||||||
.getBean(User::getSchool)
|
.getBean(User::getSchool)
|
||||||
.getBean(User.School::getAddress).orElse("没得地址");
|
.getBean(User.School::getAddress).orElse("没得地址");
|
||||||
Assert.assertEquals(value2, "没得地址");
|
Assert.assertEquals(value2, "没得地址");
|
||||||
try {
|
try {
|
||||||
OptionalBean.ofNullable(user)
|
OptionalBean.ofNullable(user)
|
||||||
.getBean(User::getSchool)
|
.getBean(User::getSchool)
|
||||||
.getBean(User.School::getAddress).orElseThrow(() -> new RuntimeException("空指针了"));
|
.getBean(User.School::getAddress).orElseThrow(() -> new RuntimeException("空指针了"));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Assert.assertEquals(e.getMessage(), "空指针了");
|
Assert.assertEquals(e.getMessage(), "空指针了");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class User {
|
public static class User {
|
||||||
private String name;
|
private String name;
|
||||||
private String gender;
|
private String gender;
|
||||||
private School school;
|
private School school;
|
||||||
@Data
|
|
||||||
public class School {
|
@Data
|
||||||
private String name;
|
public static class School {
|
||||||
private String address;
|
private String name;
|
||||||
}
|
private String address;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user