From 9818263d30523fade69b58f9f924d35ada13866a Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 21 Nov 2021 05:23:41 +0800 Subject: [PATCH] add methods --- .../main/java/cn/hutool/core/lang/Opt.java | 79 +++++++++++++------ .../java/cn/hutool/core/util/StrUtil.java | 11 +++ .../java/cn/hutool/core/lang/OptTest.java | 8 +- 3 files changed, 71 insertions(+), 27 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/Opt.java b/hutool-core/src/main/java/cn/hutool/core/lang/Opt.java index 6e8f74ac7..f3b23892c 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/Opt.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/Opt.java @@ -25,6 +25,7 @@ package cn.hutool.core.lang; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.func.Func0; import cn.hutool.core.lang.func.VoidFunc0; import cn.hutool.core.util.StrUtil; @@ -105,23 +106,25 @@ public class Opt { * @param value 传入需要包裹的元素 * @param 包裹里元素的类型 * @return 一个包裹里元素可能为空的 {@code Opt} + * @since 5.7.17 */ public static Opt> ofEmptyAble(List value) { return CollectionUtil.isEmpty(value) ? empty() : new Opt<>(value); } /** - * 执行一系列操作,如果途中发生 {@code NPE} 和 {@code IndexOutOfBoundsException},返回一个空的{@code Opt} * * @param supplier 操作 * @param 类型 * @return 操作执行后的值 */ - public static Opt exec(Supplier supplier) { + public static Opt ofTry(Func0 supplier) { try { - return Opt.ofNullable(supplier.get()); - } catch (NullPointerException | IndexOutOfBoundsException e) { - return empty(); + return Opt.ofNullable(supplier.call()); + } catch (Exception e) { + final Opt empty = Opt.empty(); + empty.exception = e; + return empty; } } @@ -129,6 +132,7 @@ public class Opt { * 包裹里实际的元素 */ private final T value; + private Exception exception; /** * {@code Opt}的构造函数 @@ -151,16 +155,7 @@ public class Opt { * @return 包裹里的元素,有可能为{@code null} */ public T get() { - return value; - } - - /** - * 判断包裹里元素的值是否存在,存在为 {@code true},否则为{@code false} - * - * @return 包裹里元素的值存在为 {@code true},否则为{@code false} - */ - public boolean isPresent() { - return value != null; + return this.value; } /** @@ -173,6 +168,37 @@ public class Opt { return value == null; } + /** + * 获取异常
+ * 当调用 {@link #ofTry(Func0)}时,异常信息不会抛出,而是保存,调用此方法获取抛出的异常 + * + * @return 异常 + * @since 5.7.17 + */ + public Exception getException(){ + return this.exception; + } + + /** + * 是否失败
+ * 当调用 {@link #ofTry(Func0)}时,抛出异常则表示失败 + * + * @return 是否失败 + * @since 5.7.17 + */ + public boolean isFail(){ + return null != this.exception; + } + + /** + * 判断包裹里元素的值是否存在,存在为 {@code true},否则为{@code false} + * + * @return 包裹里元素的值存在为 {@code true},否则为{@code false} + */ + public boolean isPresent() { + return value != null; + } + /** * 如果包裹里的值存在,就执行传入的操作({@link Consumer#accept}) * @@ -405,7 +431,18 @@ public class Opt { * @return 如果包裹里元素的值存在,则返回该值,否则返回传入的{@code other} */ public T orElse(T other) { - return value != null ? value : other; + return isPresent() ? value : other; + } + + /** + * 异常则返回另一个可选值 + * + * @param other 可选值 + * @return 如果未发生异常,则返回该值,否则返回传入的{@code other} + * @since 5.7.17 + */ + public T exceptionOrElse(T other){ + return isFail() ? other : value; } /** @@ -416,7 +453,7 @@ public class Opt { * @throws NullPointerException 如果之不存在,并且传入的操作为空,则抛出 {@code NPE} */ public T orElseGet(Supplier supplier) { - return value != null ? value : supplier.get(); + return isPresent() ? value : supplier.get(); } /** @@ -440,7 +477,7 @@ public class Opt { * @throws NullPointerException 如果值不存在并且 传入的操作为 {@code null}或者操作执行后的返回值为{@code null} */ public T orElseThrow(Supplier exceptionSupplier) throws X { - if (value != null) { + if (isPresent()) { return value; } else { throw exceptionSupplier.get(); @@ -464,7 +501,7 @@ public class Opt { * @author VampireAchao */ public T orElseThrow(Function exceptionFunction, String message) throws X { - if (value != null) { + if (isPresent()) { return value; } else { throw exceptionFunction.apply(message); @@ -526,8 +563,6 @@ public class Opt { */ @Override public String toString() { - return value != null - ? value.toString() - : null; + return StrUtil.toStringOrNull(this.value); } } diff --git a/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java index f208ad2a1..e0d6dc119 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java @@ -272,6 +272,17 @@ public class StrUtil extends CharSequenceUtil implements StrPool { return String.valueOf(obj); } + /** + * 调用对象的toString方法,null会返回{@code null} + * + * @param obj 对象 + * @return 字符串 or {@code null} + * @since 5.7.17 + */ + public static String toStringOrNull(Object obj) { + return null == obj ? null : obj.toString(); + } + /** * 创建StringBuilder对象 * diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/OptTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/OptTest.java index 013e7897d..0bdab907d 100644 --- a/hutool-core/src/test/java/cn/hutool/core/lang/OptTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/lang/OptTest.java @@ -177,12 +177,12 @@ public class OptTest { String indexOutSituation = Opt.ofEmptyAble(last).map(l -> l.get(0)).orElse("hutool"); // 现在代码整洁度降低,但可读性up,如果再人说看不懂这代码... - String npe = Opt.exec(() -> last.get(0)).orElse("hutool"); - String indexOut = Opt.exec(() -> { + String npe = Opt.ofTry(() -> last.get(0)).exceptionOrElse("hutool"); + String indexOut = Opt.ofTry(() -> { List list = new ArrayList<>(); // 你可以在里面写一长串调用链 list.get(0).getUser().getId() return list.get(0); - }).orElse("hutool"); + }).exceptionOrElse("hutool"); Assert.assertEquals(npe, npeSituation); Assert.assertEquals(indexOut, indexOutSituation); Assert.assertEquals("hutool", npe); @@ -197,6 +197,4 @@ public class OptTest { private String username; private String nickname; } - - }