add methods

This commit is contained in:
Looly
2021-11-21 05:23:41 +08:00
parent 42fbf36042
commit 9818263d30
3 changed files with 71 additions and 27 deletions

View File

@@ -25,6 +25,7 @@
package cn.hutool.core.lang; package cn.hutool.core.lang;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.func.Func0;
import cn.hutool.core.lang.func.VoidFunc0; import cn.hutool.core.lang.func.VoidFunc0;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
@@ -105,23 +106,25 @@ public class Opt<T> {
* @param value 传入需要包裹的元素 * @param value 传入需要包裹的元素
* @param <T> 包裹里元素的类型 * @param <T> 包裹里元素的类型
* @return 一个包裹里元素可能为空的 {@code Opt} * @return 一个包裹里元素可能为空的 {@code Opt}
* @since 5.7.17
*/ */
public static <T> Opt<List<T>> ofEmptyAble(List<T> value) { public static <T> Opt<List<T>> ofEmptyAble(List<T> value) {
return CollectionUtil.isEmpty(value) ? empty() : new Opt<>(value); return CollectionUtil.isEmpty(value) ? empty() : new Opt<>(value);
} }
/** /**
* 执行一系列操作,如果途中发生 {@code NPE} 和 {@code IndexOutOfBoundsException},返回一个空的{@code Opt}
* *
* @param supplier 操作 * @param supplier 操作
* @param <T> 类型 * @param <T> 类型
* @return 操作执行后的值 * @return 操作执行后的值
*/ */
public static <T> Opt<T> exec(Supplier<T> supplier) { public static <T> Opt<T> ofTry(Func0<T> supplier) {
try { try {
return Opt.ofNullable(supplier.get()); return Opt.ofNullable(supplier.call());
} catch (NullPointerException | IndexOutOfBoundsException e) { } catch (Exception e) {
return empty(); final Opt<T> empty = Opt.empty();
empty.exception = e;
return empty;
} }
} }
@@ -129,6 +132,7 @@ public class Opt<T> {
* 包裹里实际的元素 * 包裹里实际的元素
*/ */
private final T value; private final T value;
private Exception exception;
/** /**
* {@code Opt}的构造函数 * {@code Opt}的构造函数
@@ -151,16 +155,7 @@ public class Opt<T> {
* @return 包裹里的元素,有可能为{@code null} * @return 包裹里的元素,有可能为{@code null}
*/ */
public T get() { public T get() {
return value; return this.value;
}
/**
* 判断包裹里元素的值是否存在,存在为 {@code true},否则为{@code false}
*
* @return 包裹里元素的值存在为 {@code true},否则为{@code false}
*/
public boolean isPresent() {
return value != null;
} }
/** /**
@@ -173,6 +168,37 @@ public class Opt<T> {
return value == null; return value == null;
} }
/**
* 获取异常<br>
* 当调用 {@link #ofTry(Func0)}时,异常信息不会抛出,而是保存,调用此方法获取抛出的异常
*
* @return 异常
* @since 5.7.17
*/
public Exception getException(){
return this.exception;
}
/**
* 是否失败<br>
* 当调用 {@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}) * 如果包裹里的值存在,就执行传入的操作({@link Consumer#accept})
* *
@@ -405,7 +431,18 @@ public class Opt<T> {
* @return 如果包裹里元素的值存在,则返回该值,否则返回传入的{@code other} * @return 如果包裹里元素的值存在,则返回该值,否则返回传入的{@code other}
*/ */
public T orElse(T 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<T> {
* @throws NullPointerException 如果之不存在,并且传入的操作为空,则抛出 {@code NPE} * @throws NullPointerException 如果之不存在,并且传入的操作为空,则抛出 {@code NPE}
*/ */
public T orElseGet(Supplier<? extends T> supplier) { public T orElseGet(Supplier<? extends T> supplier) {
return value != null ? value : supplier.get(); return isPresent() ? value : supplier.get();
} }
/** /**
@@ -440,7 +477,7 @@ public class Opt<T> {
* @throws NullPointerException 如果值不存在并且 传入的操作为 {@code null}或者操作执行后的返回值为{@code null} * @throws NullPointerException 如果值不存在并且 传入的操作为 {@code null}或者操作执行后的返回值为{@code null}
*/ */
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X { public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) { if (isPresent()) {
return value; return value;
} else { } else {
throw exceptionSupplier.get(); throw exceptionSupplier.get();
@@ -464,7 +501,7 @@ public class Opt<T> {
* @author VampireAchao * @author VampireAchao
*/ */
public <X extends Throwable> T orElseThrow(Function<String, ? extends X> exceptionFunction, String message) throws X { public <X extends Throwable> T orElseThrow(Function<String, ? extends X> exceptionFunction, String message) throws X {
if (value != null) { if (isPresent()) {
return value; return value;
} else { } else {
throw exceptionFunction.apply(message); throw exceptionFunction.apply(message);
@@ -526,8 +563,6 @@ public class Opt<T> {
*/ */
@Override @Override
public String toString() { public String toString() {
return value != null return StrUtil.toStringOrNull(this.value);
? value.toString()
: null;
} }
} }

View File

@@ -272,6 +272,17 @@ public class StrUtil extends CharSequenceUtil implements StrPool {
return String.valueOf(obj); 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对象 * 创建StringBuilder对象
* *

View File

@@ -177,12 +177,12 @@ public class OptTest {
String indexOutSituation = Opt.ofEmptyAble(last).map(l -> l.get(0)).orElse("hutool"); String indexOutSituation = Opt.ofEmptyAble(last).map(l -> l.get(0)).orElse("hutool");
// 现在代码整洁度降低但可读性up如果再人说看不懂这代码... // 现在代码整洁度降低但可读性up如果再人说看不懂这代码...
String npe = Opt.exec(() -> last.get(0)).orElse("hutool"); String npe = Opt.ofTry(() -> last.get(0)).exceptionOrElse("hutool");
String indexOut = Opt.exec(() -> { String indexOut = Opt.ofTry(() -> {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
// 你可以在里面写一长串调用链 list.get(0).getUser().getId() // 你可以在里面写一长串调用链 list.get(0).getUser().getId()
return list.get(0); return list.get(0);
}).orElse("hutool"); }).exceptionOrElse("hutool");
Assert.assertEquals(npe, npeSituation); Assert.assertEquals(npe, npeSituation);
Assert.assertEquals(indexOut, indexOutSituation); Assert.assertEquals(indexOut, indexOutSituation);
Assert.assertEquals("hutool", npe); Assert.assertEquals("hutool", npe);
@@ -197,6 +197,4 @@ public class OptTest {
private String username; private String username;
private String nickname; private String nickname;
} }
} }