diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollStreamUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollStreamUtil.java index 8d938d29b..83adb3a4e 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollStreamUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollStreamUtil.java @@ -18,18 +18,13 @@ package org.dromara.hutool.core.collection; import org.dromara.hutool.core.collection.set.SetUtil; +import org.dromara.hutool.core.func.SerFunction; import org.dromara.hutool.core.lang.Opt; import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.core.stream.CollectorUtil; import org.dromara.hutool.core.stream.StreamUtil; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collector; @@ -53,7 +48,7 @@ public class CollStreamUtil { * @param map中的key类型 * @return 转化后的map */ - public static Map toIdentityMap(final Collection collection, final Function key) { + public static Map toIdentityMap(final Collection collection, final SerFunction key) { return toIdentityMap(collection, key, false); } @@ -69,7 +64,7 @@ public class CollStreamUtil { * @param map中的key类型 * @return 转化后的map */ - public static Map toIdentityMap(final Collection collection, final Function key, final boolean isParallel) { + public static Map toIdentityMap(final Collection collection, final SerFunction key, final boolean isParallel) { if (CollUtil.isEmpty(collection)) { return MapUtil.zero(); } @@ -230,8 +225,8 @@ public class CollStreamUtil { * @param List中的value类型 * @return 分组后的map */ - public static Map> groupKeyValue(final Collection collection, final Function key, - final Function value) { + public static Map> groupKeyValue(final Collection collection, final SerFunction key, + final SerFunction value) { return groupKeyValue(collection, key, value, false); } @@ -248,8 +243,8 @@ public class CollStreamUtil { * @param List中的value类型 * @return 分组后的map */ - public static Map> groupKeyValue(final Collection collection, final Function key, - final Function value, final boolean isParallel) { + public static Map> groupKeyValue(final Collection collection, final SerFunction key, + final SerFunction value, final boolean isParallel) { if (CollUtil.isEmpty(collection)) { return MapUtil.zero(); } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/lang/Opt.java b/hutool-core/src/main/java/org/dromara/hutool/core/lang/Opt.java index 84cfe9f83..dc9c1dcb1 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/lang/Opt.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/lang/Opt.java @@ -15,6 +15,9 @@ */ package org.dromara.hutool.core.lang; +import org.dromara.hutool.core.func.SerConsumer; +import org.dromara.hutool.core.func.SerFunction; +import org.dromara.hutool.core.func.SerPredicate; import org.dromara.hutool.core.func.SerSupplier; import org.dromara.hutool.core.stream.EasyStream; import org.dromara.hutool.core.text.StrUtil; @@ -27,7 +30,6 @@ import java.util.Optional; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; -import java.util.function.Supplier; import java.util.stream.Stream; /** @@ -128,7 +130,7 @@ public class Opt { * @since 6.0.0 */ @SuppressWarnings("OptionalUsedAsFieldOrParameterType") - public static Opt of(final Optional optional) { + public static Opt of(final Optional optional) { return ofNullable(optional.orElse(null)); } @@ -166,7 +168,6 @@ public class Opt { * 判断包裹里元素的值是否不存在,不存在为 {@code true},否则为{@code false} * * @return 包裹里元素的值不存在 则为 {@code true},否则为{@code false} - * @since 11 这是jdk11{@link java.util.Optional}中的新函数 */ public boolean isEmpty() { return value == null; @@ -261,74 +262,59 @@ public class Opt { * @return this * @throws NullPointerException 如果包裹里的值存在,但你传入的操作为{@code null}时抛出 */ - public Opt ifPresent(final Consumer action) { + public Opt ifPresent(final SerConsumer action) { if (isPresent()) { - action.accept(value); + try { + action.accepting(value); + } catch (final Throwable e) { + this.throwable = e; + } } return this; } /** * 判断包裹里的值存在并且与给定的条件是否满足 ({@link Predicate#test}执行结果是否为true) - * 如果满足条件则返回本身 - * 不满足条件或者元素本身为空时返回一个返回一个空的{@code Opt} + * 如果满足条件则返回本身
+ * 不满足条件或者元素本身为空时返回一个返回一个空的{@code Opt}
+ * predicate测试报错,则返回一个空的{@code Opt},并附带错误信息 * * @param predicate 给定的条件 * @return 如果满足条件则返回本身, 不满足条件或者元素本身为空时返回一个空的{@code Opt} * @throws NullPointerException 如果给定的条件为 {@code null}抛出{@code NPE} */ - public Opt filter(final Predicate predicate) { + public Opt filter(final SerPredicate predicate) { Objects.requireNonNull(predicate); if (isEmpty() || isFail()) { return this; - } else { - return predicate.test(value) ? this : empty(); + } + + try { + return predicate.testing(value) ? this : empty(); + } catch (final Throwable e) { + return createError(e); } } /** - * 如果包裹里的值存在,就执行传入的操作({@link Function#apply})并返回一个包裹了该操作返回值的{@code Opt} + * 如果包裹里的值存在,就执行传入的操作({@link SerFunction#applying(Object)})并返回一个包裹了该操作返回值的{@code Opt} * 如果不存在,返回一个空的{@code Opt} * * @param mapper 值存在时执行的操作 * @param 操作返回值的类型 - * @return 如果包裹里的值存在,就执行传入的操作({@link Function#apply})并返回一个包裹了该操作返回值的{@code Opt}, + * @return 如果包裹里的值存在,就执行传入的操作({@link SerFunction#applying(Object)})并返回一个包裹了该操作返回值的{@code Opt}, * 如果不存在,返回一个空的{@code Opt} * @throws NullPointerException 如果给定的操作为 {@code null},抛出 {@code NPE} */ @SuppressWarnings("unchecked") - public Opt map(final Function mapper) { + public Opt map(final SerFunction mapper) { Objects.requireNonNull(mapper); if (isFail()) { return (Opt) this; } else if (isEmpty()) { return empty(); } else { - return Opt.ofNullable(mapper.apply(value)); - } - } - - /** - * 如果包裹里的值存在,就执行传入的操作({@link Function#apply})并返回该操作返回值 - * 如果不存在,返回一个空的{@code Opt} - * 和 {@link Opt#map}的区别为 传入的操作返回值必须为 Opt - * - * @param mapper 值存在时执行的操作 - * @param 操作返回值的类型 - * @return 如果包裹里的值存在,就执行传入的操作({@link Function#apply})并返回该操作返回值 - * 如果不存在,返回一个空的{@code Opt} - * @throws NullPointerException 如果给定的操作为 {@code null}或者给定的操作执行结果为 {@code null},抛出 {@code NPE} - */ - @SuppressWarnings("unchecked") - public Opt flatMap(final Function> mapper) { - Objects.requireNonNull(mapper); - if (isFail()) { - return (Opt) this; - } else if (isEmpty()) { - return empty(); - } else { - @SuppressWarnings("unchecked") final Opt r = (Opt) mapper.apply(value); - return Objects.requireNonNull(r); + return Opt.ofTry(() -> mapper.applying(value)); } } @@ -346,39 +332,28 @@ public class Opt { * @since 5.7.16 */ @SuppressWarnings("unchecked") - public Opt flattedMap(final Function> mapper) { + public Opt flattedMap(final SerFunction> mapper) { Objects.requireNonNull(mapper); if (isFail()) { return (Opt) this; } else if (isEmpty()) { return empty(); } else { - return ofNullable(mapper.apply(value).orElse(null)); + final Optional optional; + try { + optional = mapper.applying(value); + } catch (final Throwable e) { + return createError(e); + } + return of(optional); } } - /** - * 如果包裹里元素的值存在,就执行对应的操作,并返回本身 - * 如果不存在,返回一个空的{@code Opt} - * - *

属于 {@link #ifPresent}的链式拓展 - * - * @param action 值存在时执行的操作 - * @return this - * @throws NullPointerException 如果值存在,并且传入的操作为 {@code null} - * @author VampireAchao - */ - public Opt peek(final Consumer action) throws NullPointerException { - return ifPresent(action); - } - - /** * 如果包裹里元素的值存在,就执行对应的操作集,并返回本身 * 如果不存在,返回一个空的{@code Opt} * - *

属于 {@link #ifPresent}的链式拓展 - *

属于 {@link #peek(Consumer)}的动态拓展 + *

属于 {@link #ifPresent(SerConsumer)}的动态拓展 * * @param actions 值存在时执行的操作,动态参数,可传入数组,当数组为一个空数组时并不会抛出 {@code NPE} * @return this @@ -386,9 +361,8 @@ public class Opt { * @author VampireAchao */ @SafeVarargs - public final Opt peeks(final Consumer... actions) throws NullPointerException { - return peek(Stream.of(actions).reduce(Consumer::andThen).orElseGet(() -> o -> { - })); + public final Opt ifPresents(final SerConsumer... actions) throws NullPointerException { + return ifPresent(Stream.of(actions).reduce(SerConsumer::andThen).orElseGet(() -> o -> {})); } /** @@ -398,7 +372,7 @@ public class Opt { * @return 如果包裹里元素的值存在,就返回本身,如果不存在,则使用传入的函数执行后获得的 {@code Opt} * @throws NullPointerException 如果传入的操作为空,或者传入的操作执行后返回值为空,则抛出 {@code NPE} */ - public Opt or(final Supplier> supplier) { + public Opt or(final SerSupplier> supplier) { Objects.requireNonNull(supplier); if (isPresent()) { return this; @@ -456,7 +430,7 @@ public class Opt { * @return 如果包裹里元素的值存在,则返回该值,否则返回传入的操作执行后的返回值 * @throws NullPointerException 如果之不存在,并且传入的操作为空,则抛出 {@code NPE} */ - public T orElseGet(final Supplier supplier) { + public T orElseGet(final SerSupplier supplier) { return isPresent() ? value : supplier.get(); } @@ -467,7 +441,7 @@ public class Opt { * @return 如果包裹里元素的值存在,则返回该值,否则返回传入的操作执行后的返回值 * @throws NullPointerException 如果之不存在,并且传入的操作为空,则抛出 {@code NPE} */ - public Opt orElseOpt(final Supplier supplier) { + public Opt orElseOpt(final SerSupplier supplier) { return or(() -> ofNullable(supplier.get())); } @@ -507,7 +481,7 @@ public class Opt { * @throws X 如果值不存在 * @throws NullPointerException 如果值不存在并且 传入的操作为 {@code null}或者操作执行后的返回值为{@code null} */ - public T orElseThrow(final Supplier exceptionSupplier) throws X { + public T orElseThrow(final SerSupplier exceptionSupplier) throws X { if (isPresent()) { return value; } else { @@ -581,4 +555,17 @@ public class Opt { public String toString() { return StrUtil.toStringOrNull(value); } + + /** + * 创建空的带异常的Opt + * + * @param throwable 异常 + * @param 类型 + * @return Opt + */ + private static Opt createError(final Throwable throwable) { + final Opt emptyWithError = new Opt<>(null); + emptyWithError.throwable = throwable; + return emptyWithError; + } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/lang/range/BoundedRange.java b/hutool-core/src/main/java/org/dromara/hutool/core/lang/range/BoundedRange.java index 0dcf2e687..8ea20d94d 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/lang/range/BoundedRange.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/lang/range/BoundedRange.java @@ -16,6 +16,7 @@ package org.dromara.hutool.core.lang.range; +import org.dromara.hutool.core.func.SerPredicate; import org.dromara.hutool.core.lang.Assert; import java.util.Objects; @@ -60,7 +61,8 @@ import java.util.function.Predicate; * @see Bound * @since 6.0.0 */ -public class BoundedRange> implements Predicate { +public class BoundedRange> implements SerPredicate { + private static final long serialVersionUID = 1L; /** * 双向无界的区间 @@ -93,9 +95,9 @@ public class BoundedRange> implements Predicate< Objects.requireNonNull(lowerBound); Objects.requireNonNull(upperBound); return checkEmpty( - new BoundedRange<>( - Bound.atLeast(lowerBound), Bound.atMost(upperBound) - ) + new BoundedRange<>( + Bound.atLeast(lowerBound), Bound.atMost(upperBound) + ) ); } @@ -113,7 +115,7 @@ public class BoundedRange> implements Predicate< Objects.requireNonNull(lowerBound); Objects.requireNonNull(upperBound); return checkEmpty( - new BoundedRange<>(Bound.greaterThan(lowerBound), Bound.lessThan(upperBound)) + new BoundedRange<>(Bound.greaterThan(lowerBound), Bound.lessThan(upperBound)) ); } @@ -131,10 +133,10 @@ public class BoundedRange> implements Predicate< Objects.requireNonNull(lowerBound); Objects.requireNonNull(upperBound); return checkEmpty( - new BoundedRange<>( - Bound.atLeast(lowerBound), - Bound.lessThan(upperBound) - ) + new BoundedRange<>( + Bound.atLeast(lowerBound), + Bound.lessThan(upperBound) + ) ); } @@ -152,10 +154,10 @@ public class BoundedRange> implements Predicate< Objects.requireNonNull(lowerBound); Objects.requireNonNull(upperBound); return checkEmpty( - new BoundedRange<>( - Bound.greaterThan(lowerBound), - Bound.atMost(upperBound) - ) + new BoundedRange<>( + Bound.greaterThan(lowerBound), + Bound.atMost(upperBound) + ) ); } @@ -315,8 +317,8 @@ public class BoundedRange> implements Predicate< } // 上界小于下界时为空 return compareValue > 0 - // 上下界的边界值相等,且不为退化区间是为空 - || !(low.getType().isClose() && up.getType().isClose()); + // 上下界的边界值相等,且不为退化区间是为空 + || !(low.getType().isClose() && up.getType().isClose()); } /** @@ -369,7 +371,7 @@ public class BoundedRange> implements Predicate< */ public boolean isSuperset(final BoundedRange other) { return getLowerBound().compareTo(other.getLowerBound()) <= 0 - && getUpperBound().compareTo(other.getUpperBound()) >= 0; + && getUpperBound().compareTo(other.getUpperBound()) >= 0; } /** @@ -380,7 +382,7 @@ public class BoundedRange> implements Predicate< */ public boolean isProperSuperset(final BoundedRange other) { return getLowerBound().compareTo(other.getLowerBound()) < 0 - && getUpperBound().compareTo(other.getUpperBound()) > 0; + && getUpperBound().compareTo(other.getUpperBound()) > 0; } /** @@ -391,7 +393,7 @@ public class BoundedRange> implements Predicate< */ public boolean isSubset(final BoundedRange other) { return getLowerBound().compareTo(other.getLowerBound()) >= 0 - && getUpperBound().compareTo(other.getUpperBound()) <= 0; + && getUpperBound().compareTo(other.getUpperBound()) <= 0; } /** @@ -402,7 +404,7 @@ public class BoundedRange> implements Predicate< */ public boolean isProperSubset(final BoundedRange other) { return getLowerBound().compareTo(other.getLowerBound()) > 0 - && getUpperBound().compareTo(other.getUpperBound()) < 0; + && getUpperBound().compareTo(other.getUpperBound()) < 0; } /** @@ -432,10 +434,10 @@ public class BoundedRange> implements Predicate< * @return 是否 */ @Override - public boolean test(final T value) { + public boolean testing(final T value) { return getLowerBound() - .and(getUpperBound()) - .test(value); + .and(getUpperBound()) + .test(value); } // endregion diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/pool/ObjectPool.java b/hutool-core/src/main/java/org/dromara/hutool/core/pool/ObjectPool.java index 0191e5496..95658450a 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/pool/ObjectPool.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/pool/ObjectPool.java @@ -24,8 +24,9 @@ import java.io.Serializable; *

    *
  • {@link #borrowObject()} 对象借出。
  • *
  • {@link #returnObject(Poolable)}对象归还。
  • + *
  • {@link #free(Poolable)} 对象销毁。
  • *
- * + *

* 对于对象池中对象维护,通过{@link PoolConfig#getMaxIdle()}控制,规则如下: *