From 84b973a20a94a931f7314780c725595e3ea655bd Mon Sep 17 00:00:00 2001 From: totalo Date: Sat, 24 Oct 2020 14:49:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E4=BC=98=E9=9B=85=E5=88=A4=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/hutool/core/bean/OptionalBean.java | 130 ++++++++++++++++++ .../cn/hutool/core/bean/OptionalBeanTest.java | 49 +++++++ 2 files changed, 179 insertions(+) create mode 100644 hutool-core/src/main/java/cn/hutool/core/bean/OptionalBean.java create mode 100644 hutool-core/src/test/java/cn/hutool/core/bean/OptionalBeanTest.java 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 new file mode 100644 index 000000000..21c40fa5b --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/bean/OptionalBean.java @@ -0,0 +1,130 @@ +package cn.hutool.core.bean; + +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * optional 判空 + * @param + * @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 final T value; + + private OptionalBean() { + this.value = null; + } + + /** + * 空值会抛出空指针 + * @param value + */ + private OptionalBean(T value) { + this.value = Objects.requireNonNull(value); + } + + /** + * 包装一个不能为空的 bean + * @param value + * @param + * @return + */ + public static OptionalBean of(T value) { + return new OptionalBean<>(value); + } + + /** + * 包装一个可能为空的 bean + * @param value + * @param + * @return + */ + public static OptionalBean ofNullable(T value) { + return value == null ? empty() : of(value); + } + + /** + * 取出具体的值 + * @return + */ + public T get() { + return Objects.isNull(value) ? null : value; + } + + /** + * 取出一个可能为空的对象 + * @param fn + * @param + * @return + */ + public OptionalBean getBean(Function fn) { + return Objects.isNull(value) ? OptionalBean.empty() : OptionalBean.ofNullable(fn.apply(value)); + } + + /** + * 如果目标值为空 获取一个默认值 + * @param other + * @return + */ + + public T orElse(T other) { + return value != null ? value : other; + } + + /** + * 如果目标值为空 通过lambda表达式获取一个值 + * @param other + * @return + */ + public T orElseGet(Supplier other) { + return value != null ? value : other.get(); + } + + /** + * 如果目标值为空 抛出一个异常 + * @param exceptionSupplier + * @param + * @return + * @throws X + */ + public T orElseThrow(Supplier exceptionSupplier) throws X { + if (value != null) { + return value; + } else { + throw exceptionSupplier.get(); + } + } + + public boolean isPresent() { + return value != null; + } + + public void ifPresent(Consumer consumer) { + if (value != null) { + consumer.accept(value); + } + } + + @Override + public int hashCode() { + return Objects.hashCode(value); + } + + /** + * 空值常量 + * @param + * @return + */ + public static OptionalBean empty() { + @SuppressWarnings("unchecked") + OptionalBean none = (OptionalBean) EMPTY; + return none; + } +} \ 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 new file mode 100644 index 000000000..4927b5413 --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/bean/OptionalBeanTest.java @@ -0,0 +1,49 @@ +package cn.hutool.core.bean; + +import org.junit.Assert; +import lombok.Data; +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); + + 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(), "空指针了"); + } + } + + + @Data + public class User { + private String name; + private String gender; + private School school; + @Data + public class School { + private String name; + private String address; + } + } + +}