diff --git a/uno-core/src/main/java/cc/allio/uno/core/api/Single.java b/uno-core/src/main/java/cc/allio/uno/core/api/Single.java new file mode 100644 index 00000000..1241aaf0 --- /dev/null +++ b/uno-core/src/main/java/cc/allio/uno/core/api/Single.java @@ -0,0 +1,131 @@ +package cc.allio.uno.core.api; + +import cc.allio.uno.core.exception.Exceptions; +import cc.allio.uno.core.util.CollectionUtils; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Stream; + +/** + * description 'single' value transfer and filter. + * + * @author j.x + * @date 2024/7/6 17:57 + * @since 0.1.1 + * @see Stream + */ +public interface Single { + + /** + * from {@link List} single + * + * @param list the list + * @return the {@link Single} instance + */ + static Single from(List list) { + if (CollectionUtils.isEmpty(list)) { + throw Exceptions.unNull("list"); + } + return new InternalSingle<>(list.stream()); + } + + /** + * from {@link Set} single + * + * @param set the set + * @return the {@link Single} instance + */ + static Single from(Set set) { + if (CollectionUtils.isEmpty(set)) { + throw Exceptions.unNull("set"); + } + return new InternalSingle<>(set.stream()); + } + + /** + * from {@link Map} single + * + * @param map the map + * @return the {@link Single} instance + */ + static Single from(Map map) { + if (CollectionUtils.isEmpty(map)) { + throw Exceptions.unNull("map"); + } + return (Single) new InternalSingle<>(map.entrySet().stream()); + } + + /** + * from {@link Stream} single + * + * @param stream the stream + * @return the {@link Single} instance + */ + static Single from(Stream stream) { + if (stream == null) { + throw Exceptions.unNull("map"); + } + return new InternalSingle<>(stream); + } + + /** + * single elements trigger map operator + * + * @param func the map function + * @return the {@link Single} instance + */ + Single map(Function func); + + /** + * single elements trigger filter operator + * + * @param predicate the predicate function + * @return the {@link Single} instance + */ + Single filter(Predicate predicate); + + /** + * foreach all elements, if one of through predicate, then return element of {@link Optional} instance, otherwise + * return empty + * + * @param predicate the element predicate + * @return the {@link Optional} instance + */ + Optional forReturn(Predicate predicate); + + class InternalSingle implements Single, Self> { + + private Stream stream; + + public InternalSingle(Stream stream) { + this.stream = stream; + } + + @Override + public Single map(Function func) { + return new InternalSingle<>(stream.map(func)); + } + + @Override + public Single filter(Predicate predicate) { + this.stream = stream.filter(predicate); + return self(); + } + + @Override + public Optional forReturn(Predicate predicate) { + List elements = stream.toList(); + for (E element : elements) { + if (predicate.test(element)) { + return Optional.ofNullable(element); + } + } + return Optional.empty(); + } + } +} diff --git a/uno-core/src/main/java/cc/allio/uno/core/concurrent/MultiCheckedException.java b/uno-core/src/main/java/cc/allio/uno/core/concurrent/MultiCheckedException.java index e45304dc..64d52948 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/concurrent/MultiCheckedException.java +++ b/uno-core/src/main/java/cc/allio/uno/core/concurrent/MultiCheckedException.java @@ -1,5 +1,6 @@ package cc.allio.uno.core.concurrent; +import cc.allio.uno.core.api.Single; import com.google.common.collect.Maps; import java.util.Map; @@ -14,8 +15,8 @@ public class MultiCheckedException extends Exception { // 受检查的异常 - final Map, Throwable> checked = Maps.newHashMap(); - final Map, RuntimeException> unchecked = Maps.newHashMap(); + final transient Map, Throwable> checked = Maps.newHashMap(); + final transient Map, RuntimeException> unchecked = Maps.newHashMap(); /** * 追加异常 @@ -39,11 +40,14 @@ public void appendException(T ex) { * @return Exception or null */ public T findUncheckedException(Class errType) { - RuntimeException err = unchecked.get(errType); - if (err != null) { - return (T) err; + if (hasUncheckedException(errType)) { + return (T) unchecked.get(errType); } - return null; + var err = Single.from(unchecked.entrySet()) + .forReturn(errEntry -> errEntry.getKey().isAssignableFrom(errType)) + .map(Map.Entry::getValue) + .orElse(null); + return (T) err; } /** @@ -54,11 +58,15 @@ public T findUncheckedException(Class errType) { * @return Exception or null */ public T findCheckedException(Class errType) { - Throwable err = checked.get(errType); - if (err != null) { - return (T) err; + if (hasCheckedException(errType)) { + return (T) checked.get(errType); } - return null; + var err = Single.from(checked.entrySet()) + .forReturn(errEntry -> errEntry.getKey().isAssignableFrom(errType)) + .map(Map.Entry::getValue) + .orElse(null); + + return (T) err; } /** diff --git a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/TreeSupport.java b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/TreeSupport.java index 6c765da6..d7ceddc6 100644 --- a/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/TreeSupport.java +++ b/uno-core/src/main/java/cc/allio/uno/core/datastructure/tree/TreeSupport.java @@ -170,7 +170,7 @@ static Stream doExpandFn(Collection forest, MethodFunction children = BeanWrapper.getValue(element, fieldName, Collection.class); if (CollectionUtils.isNotEmpty(children)) { - return doExpandFn(forest, childrenFunc, transfer); + return doExpandFn(children, childrenFunc, transfer); } return Stream.of(transfer.apply(element)); });