From 2b89f3fca88e3355f48d193a596990f6c0d86bf1 Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 24 Oct 2020 15:46:49 +0800 Subject: [PATCH] add OptionalBean --- CHANGELOG.md | 1 + .../cn/hutool/core/bean/OptionalBean.java | 224 ++++++++++-------- .../cn/hutool/core/bean/OptionalBeanTest.java | 71 +++--- 3 files changed, 160 insertions(+), 136 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d753c01f..0fa159d29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ # 5.4.7 (2020-10-23) ### 新特性 +* 【core 】 增加OptionalBean(pr#1182@Github) ### Bug修复 ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/OptionalBean.java b/hutool-core/src/main/java/cn/hutool/core/bean/OptionalBean.java index 21c40fa5b..9313b3b16 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/OptionalBean.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/OptionalBean.java @@ -1,130 +1,152 @@ package cn.hutool.core.bean; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.ObjectUtil; + import java.util.Objects; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; /** - * optional 判空 - * @param + * optional对象判空,参考:https://mp.weixin.qq.com/s/0c8iC0OTtx5LqPkhvkK0tw
+ * from:https://github.com/looly/hutool/pull/1182 + * + * @param Bean类型 * @author totalo * @since 5.4.7 - * @see https://mp.weixin.qq.com/s/0c8iC0OTtx5LqPkhvkK0tw */ public final class OptionalBean { - private static final OptionalBean EMPTY = new OptionalBean<>(); + private static final OptionalBean EMPTY = new OptionalBean<>(); - private final T value; + /** + * 空值常量 + * + * @param 对象类型 + * @return 空 + */ + public static OptionalBean empty() { + @SuppressWarnings("unchecked") + OptionalBean none = (OptionalBean) EMPTY; + return none; + } - private OptionalBean() { - this.value = null; - } + private final T value; - /** - * 空值会抛出空指针 - * @param value - */ - private OptionalBean(T value) { - this.value = Objects.requireNonNull(value); - } + /** + * 构造 + */ + private OptionalBean() { + this.value = null; + } - /** - * 包装一个不能为空的 bean - * @param value - * @param - * @return - */ - public static OptionalBean of(T value) { - return new OptionalBean<>(value); - } + /** + * 空值会抛出空指针 + * + * @param value Bean值 + */ + private OptionalBean(T value) { + this.value = Objects.requireNonNull(value); + } - /** - * 包装一个可能为空的 bean - * @param value - * @param - * @return - */ - public static OptionalBean ofNullable(T value) { - return value == null ? empty() : of(value); - } + /** + * 包装一个不能为空的 bean + * + * @param bean类型 + * @param value Bean值 + * @return OptionalBean + */ + public static OptionalBean of(T value) { + return new OptionalBean<>(value); + } - /** - * 取出具体的值 - * @return - */ - public T get() { - return Objects.isNull(value) ? null : value; - } + /** + * 包装一个可能为空的 bean + * + * @param value Bean值 + * @param bean类型 + * @return OptionalBean + */ + public static OptionalBean ofNullable(T value) { + return value == null ? empty() : of(value); + } - /** - * 取出一个可能为空的对象 - * @param fn - * @param - * @return - */ - public OptionalBean getBean(Function fn) { - return Objects.isNull(value) ? OptionalBean.empty() : OptionalBean.ofNullable(fn.apply(value)); - } + /** + * 取出具体的值 + * + * @return bean值 + */ + public T get() { + return value; + } - /** - * 如果目标值为空 获取一个默认值 - * @param other - * @return - */ + /** + * 取出一个可能为空的对象 + * + * @param 对象类型 + * @param fn 从已有bean中获取新bean字段的函数 + * @return 新的bean + */ + public OptionalBean getBean(Function 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 空返回默认值,否则返回原值 + */ - /** - * 如果目标值为空 通过lambda表达式获取一个值 - * @param other - * @return - */ - public T orElseGet(Supplier other) { - return value != null ? value : other.get(); - } + public T orElse(T other) { + return ObjectUtil.defaultIfNull(this.value, other); + } - /** - * 如果目标值为空 抛出一个异常 - * @param exceptionSupplier - * @param - * @return - * @throws X - */ - public T orElseThrow(Supplier exceptionSupplier) throws X { - if (value != null) { - return value; - } else { - throw exceptionSupplier.get(); - } - } + /** + * 如果目标值为空 通过lambda表达式获取一个值 + * + * @param other 默认值函数 + * @return 空返回默认值函数获得的值,否则返回原值 + */ + public T orElseGet(Supplier other) { + return null != value ? value : other.get(); + } - public boolean isPresent() { - return value != null; - } + /** + * 如果目标值为空 抛出一个异常 + * + * @param exceptionSupplier 抛出的异常 + * @param 异常类型 + * @return 非空值 + * @throws X 对象为空时抛出的异常 + */ + public T orElseThrow(Supplier exceptionSupplier) throws X { + return Assert.notNull(this.value, exceptionSupplier); + } - public void ifPresent(Consumer 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 consumer) { + if (value != null) { + consumer.accept(value); + } + } - /** - * 空值常量 - * @param - * @return - */ - public static OptionalBean empty() { - @SuppressWarnings("unchecked") - OptionalBean none = (OptionalBean) EMPTY; - return none; - } + @Override + public int hashCode() { + return Objects.hashCode(value); + } } \ No newline at end of file diff --git a/hutool-core/src/test/java/cn/hutool/core/bean/OptionalBeanTest.java b/hutool-core/src/test/java/cn/hutool/core/bean/OptionalBeanTest.java index 4927b5413..01a8312aa 100644 --- a/hutool-core/src/test/java/cn/hutool/core/bean/OptionalBeanTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/bean/OptionalBeanTest.java @@ -6,44 +6,45 @@ import org.junit.Test; public class OptionalBeanTest { - @Test - public void OptionalBeanTest() { - User user = new User(); - user.setName("hello"); - String value1 = OptionalBean.ofNullable(user) - .getBean(User::getSchool) - .getBean(User.School::getAddress).get(); - Assert.assertEquals(value1, null); + @Test + public void optionalBeanTest() { + User user = new User(); + user.setName("hello"); + String value1 = OptionalBean.ofNullable(user) + .getBean(User::getSchool) + .getBean(User.School::getAddress).get(); + Assert.assertNull(value1); - boolean present = OptionalBean.ofNullable(user) - .getBean(User::getSchool) - .getBean(User.School::getAddress).isPresent(); - Assert.assertFalse(present); + boolean present = OptionalBean.ofNullable(user) + .getBean(User::getSchool) + .getBean(User.School::getAddress).isPresent(); + Assert.assertFalse(present); - String value2 = OptionalBean.ofNullable(user) - .getBean(User::getSchool) - .getBean(User.School::getAddress).orElse("没得地址"); - Assert.assertEquals(value2, "没得地址"); - try { - OptionalBean.ofNullable(user) - .getBean(User::getSchool) - .getBean(User.School::getAddress).orElseThrow(() -> new RuntimeException("空指针了")); - } catch (Exception e) { - Assert.assertEquals(e.getMessage(), "空指针了"); - } - } + String value2 = OptionalBean.ofNullable(user) + .getBean(User::getSchool) + .getBean(User.School::getAddress).orElse("没得地址"); + Assert.assertEquals(value2, "没得地址"); + try { + OptionalBean.ofNullable(user) + .getBean(User::getSchool) + .getBean(User.School::getAddress).orElseThrow(() -> new RuntimeException("空指针了")); + } catch (Exception e) { + Assert.assertEquals(e.getMessage(), "空指针了"); + } + } - @Data - public class User { - private String name; - private String gender; - private School school; - @Data - public class School { - private String name; - private String address; - } - } + @Data + public static class User { + private String name; + private String gender; + private School school; + + @Data + public static class School { + private String name; + private String address; + } + } }