重构Jdk自带的Lambda体系,支持序列化+包裹受检异常

改动如下:
1. AnnotationUtil 115行 简化 predicate::test 为 predicate
2. 调整 Func1 为 SerFunction
3. 调整 Func0 为 SerSupplier
4. 移除 GenericBuilder 对于多参数构造双冒号简写支持,直接采用lambda方式,例如GenericBuilder.of(Box::new, 2048L, "Hello Partner!", 222, 333, 444)改为GenericBuilder.of(() -> new Box(2048L, "Hello Partner!", 222, 333, 444))
5. 移除 CheckedUtil,现有重构后的Lambda 支持包裹异常
6. 移除 Func,该函数式接口属于泛型可变参数,不推荐使用
7. 移除 Supplier1,1参数Supplier应该使用SerFunction替代
8. 移除 Supplier2,2参数Supplier应该使用SerBiFunction替代
9. 移除 Supplier3,3参数Supplier应该使用SerFunction3替代(因第4条更改思路,该SerFunction3并未添加)
10. 移除 Supplier4,4参数Supplier应该使用SerFunction4替代(因第4条更改思路,该SerFunction4并未添加)
11. 移除 Supplier5,5参数Supplier应该使用SerFunction5替代(因第4条更改思路,该SerFunction5并未添加)
12. 移除 VoidFunc,该函数式接口属于泛型可变参数,不推荐使用
13. 调整 VoidFunc0 为 SerRunnable
14. 调整 VoidFunc1 为 SerConsumer
15. 调整 EntryStream 泛型命名、完善javadoc
16. EnumUtil 273行 简化 field::callWithRuntimeException 为 field
This commit is contained in:
achao 2022-09-07 15:08:11 +08:00 committed by VampireAchao
parent 4204cb8532
commit f732d14809
52 changed files with 1064 additions and 1137 deletions

View File

@ -112,7 +112,7 @@ public class AnnotationUtil {
if (null == predicate) { if (null == predicate) {
return result; return result;
} }
return ArrayUtil.filter(result, predicate::test); return ArrayUtil.filter(result, predicate);
} }
/** /**

View File

@ -1,6 +1,6 @@
package cn.hutool.core.bean; package cn.hutool.core.bean;
import cn.hutool.core.lang.func.Func0; import cn.hutool.core.lang.func.SerSupplier;
import cn.hutool.core.map.WeakConcurrentMap; import cn.hutool.core.map.WeakConcurrentMap;
/** /**
@ -22,8 +22,8 @@ public enum BeanDescCache {
* @return 属性名和{@link BeanDesc}映射 * @return 属性名和{@link BeanDesc}映射
* @since 5.4.2 * @since 5.4.2
*/ */
public BeanDesc getBeanDesc(final Class<?> beanClass, final Func0<BeanDesc> supplier) { public BeanDesc getBeanDesc(final Class<?> beanClass, final SerSupplier<BeanDesc> supplier) {
return bdCache.computeIfAbsent(beanClass, (key)->supplier.callWithRuntimeException()); return bdCache.computeIfAbsent(beanClass, (key) -> supplier.get());
} }
/** /**

View File

@ -1,6 +1,6 @@
package cn.hutool.core.bean; package cn.hutool.core.bean;
import cn.hutool.core.lang.func.Func0; import cn.hutool.core.lang.func.SerSupplier;
import cn.hutool.core.map.ReferenceConcurrentMap; import cn.hutool.core.map.ReferenceConcurrentMap;
import cn.hutool.core.map.WeakConcurrentMap; import cn.hutool.core.map.WeakConcurrentMap;
@ -42,8 +42,8 @@ public enum BeanInfoCache {
public Map<String, PropertyDescriptor> getPropertyDescriptorMap( public Map<String, PropertyDescriptor> getPropertyDescriptorMap(
final Class<?> beanClass, final Class<?> beanClass,
final boolean ignoreCase, final boolean ignoreCase,
final Func0<Map<String, PropertyDescriptor>> supplier) { final SerSupplier<Map<String, PropertyDescriptor>> supplier) {
return getCache(ignoreCase).computeIfAbsent(beanClass, (key)->supplier.callWithRuntimeException()); return getCache(ignoreCase).computeIfAbsent(beanClass, (key) -> supplier.get());
} }
/** /**

View File

@ -2,8 +2,8 @@ package cn.hutool.core.bean.copier;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.convert.Converter; import cn.hutool.core.convert.Converter;
import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.lang.func.LambdaUtil; import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.lang.func.SerFunction;
import cn.hutool.core.lang.mutable.MutableEntry; import cn.hutool.core.lang.mutable.MutableEntry;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
@ -178,7 +178,7 @@ public class CopyOptions implements Serializable {
* @since 5.8.0 * @since 5.8.0
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <P, R> CopyOptions setIgnoreProperties(final Func1<P, R>... funcs) { public <P, R> CopyOptions setIgnoreProperties(final SerFunction<P, R>... funcs) {
final Set<String> ignoreProperties = ArrayUtil.mapToSet(funcs, LambdaUtil::getFieldName); final Set<String> ignoreProperties = ArrayUtil.mapToSet(funcs, LambdaUtil::getFieldName);
return setPropertiesFilter((field, o) -> false == ignoreProperties.contains(field.getName())); return setPropertiesFilter((field, o) -> false == ignoreProperties.contains(field.getName()));
} }

View File

@ -1,11 +1,6 @@
package cn.hutool.core.builder; package cn.hutool.core.builder;
import cn.hutool.core.lang.func.Consumer3; import cn.hutool.core.lang.func.SerConsumer3;
import cn.hutool.core.lang.func.Supplier1;
import cn.hutool.core.lang.func.Supplier2;
import cn.hutool.core.lang.func.Supplier3;
import cn.hutool.core.lang.func.Supplier4;
import cn.hutool.core.lang.func.Supplier5;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -58,7 +53,7 @@ import java.util.function.Supplier;
* *
* <p>注意本工具类支持调用的构造方法的参数数量不超过5个一般方法的参数数量不超过2个更多的参数不利于阅读和维护</p> * <p>注意本工具类支持调用的构造方法的参数数量不超过5个一般方法的参数数量不超过2个更多的参数不利于阅读和维护</p>
* *
* @author TomXin * @author TomXin VampireAchao
* @since 5.7.21 * @since 5.7.21
*/ */
public class GenericBuilder<T> implements Builder<T> { public class GenericBuilder<T> implements Builder<T> {
@ -84,7 +79,7 @@ public class GenericBuilder<T> implements Builder<T> {
} }
/** /**
* 通过无参数实例化器创建GenericBuilder * 通过Supplier创建GenericBuilder
* *
* @param instant 实例化器 * @param instant 实例化器
* @param <T> 目标类型 * @param <T> 目标类型
@ -94,92 +89,6 @@ public class GenericBuilder<T> implements Builder<T> {
return new GenericBuilder<>(instant); return new GenericBuilder<>(instant);
} }
/**
* 通过1参数实例化器创建GenericBuilder
*
* @param instant 实例化器
* @param p1 参数一
* @param <T> 目标类型
* @param <P1> 参数一类型
* @return GenericBuilder对象
*/
public static <T, P1> GenericBuilder<T> of(final Supplier1<T, P1> instant, final P1 p1) {
return of(instant.toSupplier(p1));
}
/**
* 通过2参数实例化器创建GenericBuilder
*
* @param instant 实例化器
* @param p1 参数一
* @param p2 参数二
* @param <T> 目标类型
* @param <P1> 参数一类型
* @param <P2> 参数二类型
* @return GenericBuilder对象
*/
public static <T, P1, P2> GenericBuilder<T> of(final Supplier2<T, P1, P2> instant, final P1 p1, final P2 p2) {
return of(instant.toSupplier(p1, p2));
}
/**
* 通过3参数实例化器创建GenericBuilder
*
* @param instant 实例化器
* @param p1 参数一
* @param p2 参数二
* @param p3 参数三
* @param <T> 目标类型
* @param <P1> 参数一类型
* @param <P2> 参数二类型
* @param <P3> 参数三类型
* @return GenericBuilder对象
*/
public static <T, P1, P2, P3> GenericBuilder<T> of(final Supplier3<T, P1, P2, P3> instant, final P1 p1, final P2 p2, final P3 p3) {
return of(instant.toSupplier(p1, p2, p3));
}
/**
* 通过4参数实例化器创建GenericBuilder
*
* @param instant 实例化器
* @param p1 参数一
* @param p2 参数二
* @param p3 参数三
* @param p4 参数四
* @param <T> 目标类型
* @param <P1> 参数一类型
* @param <P2> 参数二类型
* @param <P3> 参数三类型
* @param <P4> 参数四类型
* @return GenericBuilder对象
*/
public static <T, P1, P2, P3, P4> GenericBuilder<T> of(final Supplier4<T, P1, P2, P3, P4> instant, final P1 p1, final P2 p2, final P3 p3, final P4 p4) {
return of(instant.toSupplier(p1, p2, p3, p4));
}
/**
* 通过5参数实例化器创建GenericBuilder
*
* @param instant 实例化器
* @param p1 参数一
* @param p2 参数二
* @param p3 参数三
* @param p4 参数四
* @param p5 参数五
* @param <T> 目标类型
* @param <P1> 参数一类型
* @param <P2> 参数二类型
* @param <P3> 参数三类型
* @param <P4> 参数四类型
* @param <P5> 参数五类型
* @return GenericBuilder对象
*/
public static <T, P1, P2, P3, P4, P5> GenericBuilder<T> of(final Supplier5<T, P1, P2, P3, P4, P5> instant, final P1 p1, final P2 p2, final P3 p3, final P4 p4, final P5 p5) {
return of(instant.toSupplier(p1, p2, p3, p4, p5));
}
/** /**
* 调用无参数方法 * 调用无参数方法
* *
@ -215,7 +124,7 @@ public class GenericBuilder<T> implements Builder<T> {
* @param <P2> 参数二类型 * @param <P2> 参数二类型
* @return GenericBuilder对象 * @return GenericBuilder对象
*/ */
public <P1, P2> GenericBuilder<T> with(final Consumer3<T, P1, P2> consumer, final P1 p1, final P2 p2) { public <P1, P2> GenericBuilder<T> with(final SerConsumer3<T, P1, P2> consumer, final P1 p1, final P2 p2) {
modifiers.add(instant -> consumer.accept(instant, p1, p2)); modifiers.add(instant -> consumer.accept(instant, p1, p2));
return this; return this;
} }

View File

@ -1,7 +1,7 @@
package cn.hutool.core.cache; package cn.hutool.core.cache;
import cn.hutool.core.cache.impl.CacheObj; import cn.hutool.core.cache.impl.CacheObj;
import cn.hutool.core.lang.func.Func0; import cn.hutool.core.lang.func.SerSupplier;
import java.io.Serializable; import java.io.Serializable;
import java.util.Iterator; import java.util.Iterator;
@ -11,7 +11,7 @@ import java.util.Iterator;
* *
* @param <K> 键类型 * @param <K> 键类型
* @param <V> 值类型 * @param <V> 值类型
* @author Looly, jodd * @author Looly, jodd, VampireAchao
*/ */
public interface Cache<K, V> extends Iterable<V>, Serializable { public interface Cache<K, V> extends Iterable<V>, Serializable {
@ -64,7 +64,7 @@ public interface Cache<K, V> extends Iterable<V>, Serializable {
} }
/** /**
* 从缓存中获得对象当对象不在缓存中或已经过期返回Func0回调产生的对象 * 从缓存中获得对象当对象不在缓存中或已经过期返回SerSupplier回调产生的对象
* <p> * <p>
* 调用此方法时会检查上次调用时间如果与当前时间差值大于超时时间返回{@code null}否则返回值 * 调用此方法时会检查上次调用时间如果与当前时间差值大于超时时间返回{@code null}否则返回值
* <p> * <p>
@ -74,12 +74,12 @@ public interface Cache<K, V> extends Iterable<V>, Serializable {
* @param supplier 如果不存在回调方法用于生产值对象 * @param supplier 如果不存在回调方法用于生产值对象
* @return 值对象 * @return 值对象
*/ */
default V get(final K key, final Func0<V> supplier) { default V get(final K key, final SerSupplier<V> supplier) {
return get(key, true, supplier); return get(key, true, supplier);
} }
/** /**
* 从缓存中获得对象当对象不在缓存中或已经过期返回Func0回调产生的对象 * 从缓存中获得对象当对象不在缓存中或已经过期返回SerSupplier回调产生的对象
* <p> * <p>
* 调用此方法时会检查上次调用时间如果与当前时间差值大于超时时间返回{@code null}否则返回值 * 调用此方法时会检查上次调用时间如果与当前时间差值大于超时时间返回{@code null}否则返回值
* <p> * <p>
@ -90,7 +90,7 @@ public interface Cache<K, V> extends Iterable<V>, Serializable {
* @param supplier 如果不存在回调方法用于生产值对象 * @param supplier 如果不存在回调方法用于生产值对象
* @return 值对象 * @return 值对象
*/ */
V get(K key, boolean isUpdateLastAccess, Func0<V> supplier); V get(K key, boolean isUpdateLastAccess, SerSupplier<V> supplier);
/** /**
* 从缓存中获得对象当对象不在缓存中或已经过期返回{@code null} * 从缓存中获得对象当对象不在缓存中或已经过期返回{@code null}
@ -168,7 +168,7 @@ public interface Cache<K, V> extends Iterable<V>, Serializable {
* @return this * @return this
* @since 5.5.2 * @since 5.5.2
*/ */
default Cache<K, V> setListener(final CacheListener<K, V> listener){ default Cache<K, V> setListener(final CacheListener<K, V> listener) {
return this; return this;
} }
} }

View File

@ -1,7 +1,7 @@
package cn.hutool.core.cache; package cn.hutool.core.cache;
import cn.hutool.core.collection.iter.TransIter; import cn.hutool.core.collection.iter.TransIter;
import cn.hutool.core.lang.func.Func0; import cn.hutool.core.lang.func.SerSupplier;
import cn.hutool.core.lang.mutable.Mutable; import cn.hutool.core.lang.mutable.Mutable;
import cn.hutool.core.lang.mutable.MutableObj; import cn.hutool.core.lang.mutable.MutableObj;
import cn.hutool.core.map.WeakConcurrentMap; import cn.hutool.core.map.WeakConcurrentMap;
@ -22,7 +22,7 @@ import java.util.function.Predicate;
* *
* @param <K> 键类型 * @param <K> 键类型
* @param <V> 值类型 * @param <V> 值类型
* @author Looly * @author Looly, VampireAchao
*/ */
public class SimpleCache<K, V> implements Iterable<Map.Entry<K, V>>, Serializable { public class SimpleCache<K, V> implements Iterable<Map.Entry<K, V>>, Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -75,18 +75,18 @@ public class SimpleCache<K, V> implements Iterable<Map.Entry<K, V>>, Serializabl
} }
/** /**
* 从缓存中获得对象当对象不在缓存中或已经过期返回Func0回调产生的对象 * 从缓存中获得对象当对象不在缓存中或已经过期返回SerSupplier回调产生的对象
* *
* @param key * @param key
* @param supplier 如果不存在回调方法用于生产值对象 * @param supplier 如果不存在回调方法用于生产值对象
* @return 值对象 * @return 值对象
*/ */
public V get(final K key, final Func0<V> supplier) { public V get(final K key, final SerSupplier<V> supplier) {
return get(key, null, supplier); return get(key, null, supplier);
} }
/** /**
* 从缓存中获得对象当对象不在缓存中或已经过期返回Func0回调产生的对象 * 从缓存中获得对象当对象不在缓存中或已经过期返回SerSupplier回调产生的对象
* *
* @param key * @param key
* @param validPredicate 检查结果对象是否可用如是否断开连接等 * @param validPredicate 检查结果对象是否可用如是否断开连接等
@ -94,9 +94,9 @@ public class SimpleCache<K, V> implements Iterable<Map.Entry<K, V>>, Serializabl
* @return 值对象 * @return 值对象
* @since 5.7.9 * @since 5.7.9
*/ */
public V get(final K key, final Predicate<V> validPredicate, final Func0<V> supplier) { public V get(final K key, final Predicate<V> validPredicate, final SerSupplier<V> supplier) {
V v = get(key); V v = get(key);
if((null != validPredicate && null != v && false == validPredicate.test(v))){ if ((null != validPredicate && null != v && false == validPredicate.test(v))) {
v = null; v = null;
} }
if (null == v && null != supplier) { if (null == v && null != supplier) {
@ -107,11 +107,7 @@ public class SimpleCache<K, V> implements Iterable<Map.Entry<K, V>>, Serializabl
// 双重检查防止在竞争锁的过程中已经有其它线程写入 // 双重检查防止在竞争锁的过程中已经有其它线程写入
v = get(key); v = get(key);
if (null == v || (null != validPredicate && false == validPredicate.test(v))) { if (null == v || (null != validPredicate && false == validPredicate.test(v))) {
try { v = supplier.get();
v = supplier.call();
} catch (final Exception e) {
throw new RuntimeException(e);
}
put(key, v); put(key, v);
} }
} finally { } finally {
@ -172,7 +168,7 @@ public class SimpleCache<K, V> implements Iterable<Map.Entry<K, V>>, Serializabl
@Override @Override
public Iterator<Map.Entry<K, V>> iterator() { public Iterator<Map.Entry<K, V>> iterator() {
return new TransIter<>(this.rawMap.entrySet().iterator(), (entry)-> new Map.Entry<K, V>() { return new TransIter<>(this.rawMap.entrySet().iterator(), (entry) -> new Map.Entry<K, V>() {
@Override @Override
public K getKey() { public K getKey() {
return entry.getKey().get(); return entry.getKey().get();

View File

@ -2,7 +2,7 @@ package cn.hutool.core.cache.impl;
import cn.hutool.core.cache.Cache; import cn.hutool.core.cache.Cache;
import cn.hutool.core.cache.CacheListener; import cn.hutool.core.cache.CacheListener;
import cn.hutool.core.lang.func.Func0; import cn.hutool.core.lang.func.SerSupplier;
import cn.hutool.core.lang.mutable.Mutable; import cn.hutool.core.lang.mutable.Mutable;
import cn.hutool.core.lang.mutable.MutableObj; import cn.hutool.core.lang.mutable.MutableObj;
@ -92,6 +92,7 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
// ---------------------------------------------------------------- put end // ---------------------------------------------------------------- put end
// ---------------------------------------------------------------- get start // ---------------------------------------------------------------- get start
/** /**
* @return 命中数 * @return 命中数
*/ */
@ -107,7 +108,7 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
} }
@Override @Override
public V get(final K key, final boolean isUpdateLastAccess, final Func0<V> supplier) { public V get(final K key, final boolean isUpdateLastAccess, final SerSupplier<V> supplier) {
V v = get(key, isUpdateLastAccess); V v = get(key, isUpdateLastAccess);
if (null == v && null != supplier) { if (null == v && null != supplier) {
//每个key单独获取一把锁降低锁的粒度提高并发能力see pr#1385@Github //每个key单独获取一把锁降低锁的粒度提高并发能力see pr#1385@Github
@ -117,11 +118,7 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
// 双重检查锁防止在竞争锁的过程中已经有其它线程写入 // 双重检查锁防止在竞争锁的过程中已经有其它线程写入
final CacheObj<K, V> co = getWithoutLock(key); final CacheObj<K, V> co = getWithoutLock(key);
if (null == co || co.isExpired()) { if (null == co || co.isExpired()) {
try { v = supplier.get();
v = supplier.call();
} catch (final Exception e) {
throw new RuntimeException(e);
}
put(key, v, this.timeout); put(key, v, this.timeout);
} else { } else {
v = co.get(isUpdateLastAccess); v = co.get(isUpdateLastAccess);
@ -136,11 +133,12 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
/** /**
* 获取键对应的{@link CacheObj} * 获取键对应的{@link CacheObj}
*
* @param key 实际使用时会被包装为{@link MutableObj} * @param key 实际使用时会被包装为{@link MutableObj}
* @return {@link CacheObj} * @return {@link CacheObj}
* @since 5.8.0 * @since 5.8.0
*/ */
protected CacheObj<K, V> getWithoutLock(final K key){ protected CacheObj<K, V> getWithoutLock(final K key) {
return this.cacheMap.get(MutableObj.of(key)); return this.cacheMap.get(MutableObj.of(key));
} }
// ---------------------------------------------------------------- get end // ---------------------------------------------------------------- get end
@ -151,6 +149,7 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
return new CacheValuesIterator<>(copiedIterator); return new CacheValuesIterator<>(copiedIterator);
} }
// ---------------------------------------------------------------- prune start // ---------------------------------------------------------------- prune start
/** /**
* 清理实现<br> * 清理实现<br>
* 子类实现此方法时无需加锁 * 子类实现此方法时无需加锁
@ -224,7 +223,7 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
* @return 所有键 * @return 所有键
* @since 5.5.9 * @since 5.5.9
*/ */
public Set<K> keySet(){ public Set<K> keySet() {
return this.cacheMap.keySet().stream().map(Mutable::get).collect(Collectors.toSet()); return this.cacheMap.keySet().stream().map(Mutable::get).collect(Collectors.toSet());
} }
@ -260,10 +259,11 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
/** /**
* 获取所有{@link CacheObj}值的{@link Iterator}形式 * 获取所有{@link CacheObj}值的{@link Iterator}形式
*
* @return {@link Iterator} * @return {@link Iterator}
* @since 5.8.0 * @since 5.8.0
*/ */
protected Iterator<CacheObj<K, V>> cacheObjIter(){ protected Iterator<CacheObj<K, V>> cacheObjIter() {
return this.cacheMap.values().iterator(); return this.cacheMap.values().iterator();
} }
} }

View File

@ -1,7 +1,7 @@
package cn.hutool.core.cache.impl; package cn.hutool.core.cache.impl;
import cn.hutool.core.cache.Cache; import cn.hutool.core.cache.Cache;
import cn.hutool.core.lang.func.Func0; import cn.hutool.core.lang.func.SerSupplier;
import java.util.Iterator; import java.util.Iterator;
@ -10,7 +10,7 @@ import java.util.Iterator;
* *
* @param <K> 键类型 * @param <K> 键类型
* @param <V> 值类型 * @param <V> 值类型
* @author Looly,jodd * @author Looly, jodd, VampireAchao
*/ */
public class NoCache<K, V> implements Cache<K, V> { public class NoCache<K, V> implements Cache<K, V> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -51,17 +51,13 @@ public class NoCache<K, V> implements Cache<K, V> {
} }
@Override @Override
public V get(final K key, final Func0<V> supplier) { public V get(final K key, final SerSupplier<V> supplier) {
return get(key, true, supplier); return get(key, true, supplier);
} }
@Override @Override
public V get(final K key, final boolean isUpdateLastAccess, final Func0<V> supplier) { public V get(final K key, final boolean isUpdateLastAccess, final SerSupplier<V> supplier) {
try { return (null == supplier) ? null : supplier.get();
return (null == supplier) ? null : supplier.call();
} catch (final Exception e) {
throw new RuntimeException(e);
}
} }
@Override @Override

View File

@ -1,332 +0,0 @@
package cn.hutool.core.exceptions;
import cn.hutool.core.lang.func.Func;
import cn.hutool.core.lang.func.Func0;
import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.lang.func.Supplier1;
import cn.hutool.core.lang.func.VoidFunc;
import cn.hutool.core.lang.func.VoidFunc0;
import cn.hutool.core.lang.func.VoidFunc1;
import java.util.Objects;
/**
* TODO 按照https://github.com/dromara/hutool/issues/2549修改
* 方便的执行会抛出受检查类型异常的方法调用或者代码段
* <p>
* 该工具通过函数式的方式将那些需要抛出受检查异常的表达式或者代码段转化成一个 cn.hutool.core.lang.func.Func* 对象
* </p>
* <p>
* {@code
* <pre>
* //代码中如果遇到一个方法调用声明了受检查异常那么我们的代码就必须这样写
* Map<String, String> describedObject = null;
* try {
* describe = BeanUtils.describe(new Object());
* } catch (IllegalAccessException e) {
* throw new RuntimeException(e);
* } catch (InvocationTargetException e) {
* throw new RuntimeException(e);
* } catch (NoSuchMethodException e) {
* throw new RuntimeException(e);
* }
* // use describedObject ...
*
* //上面的代码增加了异常块使得代码不那么流畅现在可以这样写
* Map<String, String> describedObject = CheckedUtil.uncheck(BeanUtils::describe).call(new Object());
* // use describedObject ...
*
* CheckedUtil.uncheck 方法接受任意可以转化成 cn.hutool.core.lang.func.Func* 函数式接口的 Lambda 表达式返回对应的函数式对象
* 上述代码可以理解为
* Func0<Object, Map<String, String>> aFunc = CheckedUtil.uncheck(BeanUtils::describe);
* Map<String, String> describedObject = aFunc.call(传入参数);
* 该aFunc对象代表的就是BeanUtils::describe这个表达式且在内部转化了检查类型异常不需要代码里面显示处理
*
*
* </pre>
* }
*
* @author conder
* @since 5.7.19
*/
public class CheckedUtil {
/**
* 接收一个可以转化成 cn.hutool.core.lang.func.Func 的Lambda表达式当执行表达式抛出任何异常的时候都会转化成运行时异常
* 如此一来代码中就不用显示的try-catch转化成运行时异常
*
* @param expression Lambda表达式
* @param <P> 运行时传入的参数类型
* @param <R> 最终返回的数据类型
* @return {@link FuncRt}
*/
public static <P, R> FuncRt<P, R> uncheck(final Func<P, R> expression) {
return uncheck(expression, RuntimeException::new);
}
/**
* 接收一个可以转化成 cn.hutool.core.lang.func.Func0 的Lambda表达式当执行表达式抛出任何异常的时候都会转化成运行时异常
* 如此一来代码中就不用显示的try-catch转化成运行时异常
*
* @param expression 运行时传入的参数类型
* @param <R> 最终返回的数据类型
* @return {@link Func0Rt}
*/
public static <R> Func0Rt<R> uncheck(final Func0<R> expression) {
return uncheck(expression, RuntimeException::new);
}
/**
* 接收一个可以转化成 cn.hutool.core.lang.func.Func1 的Lambda表达式当执行表达式抛出任何异常的时候都会转化成运行时异常
* 如此一来代码中就不用显示的try-catch转化成运行时异常
*
* @param expression 运行时传入的参数类型
* @param <P> 运行时传入的参数类型
* @param <R> 最终返回的数据类型
* @return {@link Func1Rt}
*/
public static <P, R> Func1Rt<P, R> uncheck(final Func1<P, R> expression) {
return uncheck(expression, RuntimeException::new);
}
/**
* 接收一个可以转化成 cn.hutool.core.lang.func.VoidFunc 的Lambda表达式当执行表达式抛出任何异常的时候都会转化成运行时异常
* 如此一来代码中就不用显示的try-catch转化成运行时异常
*
* @param expression 运行时传入的参数类型
* @param <P> 运行时传入的参数类型
* @return {@link VoidFuncRt}
*/
public static <P> VoidFuncRt<P> uncheck(final VoidFunc<P> expression) {
return uncheck(expression, RuntimeException::new);
}
/**
* 接收一个可以转化成 cn.hutool.core.lang.func.VoidFunc0 的Lambda表达式当执行表达式抛出任何异常的时候都会转化成运行时异常
* 如此一来代码中就不用显示的try-catch转化成运行时异常
*
* @param expression 运行时传入的参数类型
* @return {@link VoidFunc0Rt}
*/
public static VoidFunc0Rt uncheck(final VoidFunc0 expression) {
return uncheck(expression, RuntimeException::new);
}
/**
* 接收一个可以转化成 cn.hutool.core.lang.func.VoidFunc1 的Lambda表达式当执行表达式抛出任何异常的时候都会转化成运行时异常
* 如此一来代码中就不用显示的try-catch转化成运行时异常
*
* @param expression 运行时传入的参数类型
* @param <P> 运行时传入的参数类型
* @return {@link VoidFunc1Rt}
*/
public static <P> VoidFunc1Rt<P> uncheck(final VoidFunc1<P> expression) {
return uncheck(expression, RuntimeException::new);
}
/**
* 接收一个可以转化成 cn.hutool.core.lang.func.Func的Lambda表达式和一个可以把Exception转化成RuntimeExceptionde的表达式当执行表达式抛出任何异常的时候都会转化成运行时异常
* 如此一来代码中就不用显示的try-catch转化成运行时异常
*
* @param expression Lambda表达式
* @param rteSupplier 转化运行时异常的表达式
* @param <P> 运行时传入的参数类型
* @param <R> 最终返回的数据类型
* @return {@link FuncRt}
*/
public static <P, R> FuncRt<P, R> uncheck(final Func<P, R> expression, final Supplier1<RuntimeException, Exception> rteSupplier) {
Objects.requireNonNull(expression, "expression can not be null");
return t -> {
try {
return expression.call(t);
} catch (final Exception e) {
if (rteSupplier == null) {
throw new RuntimeException(e);
} else {
throw rteSupplier.get(e);
}
}
};
}
/**
* 接收一个可以转化成 cn.hutool.core.lang.func.Func0的Lambda表达式和一个可以把Exception转化成RuntimeExceptionde的表达式当执行表达式抛出任何异常的时候都会转化成运行时异常
* 如此一来代码中就不用显示的try-catch转化成运行时异常
*
* @param expression Lambda表达式
* @param rteSupplier 转化运行时异常的表达式
* @param <R> 最终返回的数据类型
* @return {@link Func0Rt}
*/
public static <R> Func0Rt<R> uncheck(final Func0<R> expression, final Supplier1<RuntimeException, Exception> rteSupplier) {
Objects.requireNonNull(expression, "expression can not be null");
return () -> {
try {
return expression.call();
} catch (final Exception e) {
if (rteSupplier == null) {
throw new RuntimeException(e);
} else {
throw rteSupplier.get(e);
}
}
};
}
/**
* 接收一个可以转化成 cn.hutool.core.lang.func.Func1的Lambda表达式和一个可以把Exception转化成RuntimeExceptionde的表达式当执行表达式抛出任何异常的时候都会转化成运行时异常
* 如此一来代码中就不用显示的try-catch转化成运行时异常
*
* @param expression Lambda表达式
* @param rteSupplier 转化运行时异常的表达式
* @param <P> 运行时传入的参数类型
* @param <R> 最终返回的数据类型
* @return {@link Func1Rt}
*/
public static <P, R> Func1Rt<P, R> uncheck(final Func1<P, R> expression, final Supplier1<RuntimeException, Exception> rteSupplier) {
Objects.requireNonNull(expression, "expression can not be null");
return t -> {
try {
return expression.call(t);
} catch (final Exception e) {
if (rteSupplier == null) {
throw new RuntimeException(e);
} else {
throw rteSupplier.get(e);
}
}
};
}
/**
* 接收一个可以转化成 cn.hutool.core.lang.func.VoidFunc的Lambda表达式和一个可以把Exception转化成RuntimeExceptionde的表达式当执行表达式抛出任何异常的时候都会转化成运行时异常
* 如此一来代码中就不用显示的try-catch转化成运行时异常
*
* @param expression Lambda表达式
* @param rteSupplier 转化运行时异常的表达式
* @param <P> 运行时传入的参数类型
* @return {@link VoidFuncRt}
*/
public static <P> VoidFuncRt<P> uncheck(final VoidFunc<P> expression, final Supplier1<RuntimeException, Exception> rteSupplier) {
Objects.requireNonNull(expression, "expression can not be null");
return t -> {
try {
expression.call(t);
} catch (final Exception e) {
if (rteSupplier == null) {
throw new RuntimeException(e);
} else {
throw rteSupplier.get(e);
}
}
};
}
/**
* 接收一个可以转化成 cn.hutool.core.lang.func.VoidFunc0的Lambda表达式和一个RuntimeException当执行表达式抛出任何异常的时候都会转化成运行时异常
* 如此一来代码中就不用显示的try-catch转化成运行时异常
*
* @param expression Lambda表达式
* @param rte 期望抛出的运行时异常
* @return {@link VoidFunc0Rt}
*/
public static VoidFunc0Rt uncheck(final VoidFunc0 expression, final RuntimeException rte) {
Objects.requireNonNull(expression, "expression can not be null");
return () -> {
try {
expression.call();
} catch (final Exception e) {
if (rte == null) {
throw new RuntimeException(e);
} else {
rte.initCause(e);
throw rte;
}
}
};
}
/**
* 接收一个可以转化成 cn.hutool.core.lang.func.VoidFunc0的Lambda表达式和一个可以把Exception转化成RuntimeExceptionde的表达式当执行表达式抛出任何异常的时候都会转化成运行时异常
* 如此一来代码中就不用显示的try-catch转化成运行时异常
*
* @param expression Lambda表达式
* @param rteSupplier 转化运行时异常的表达式
* @return {@link VoidFunc0Rt}
*/
public static VoidFunc0Rt uncheck(final VoidFunc0 expression, final Supplier1<RuntimeException, Exception> rteSupplier) {
Objects.requireNonNull(expression, "expression can not be null");
return () -> {
try {
expression.call();
} catch (final Exception e) {
if (rteSupplier == null) {
throw new RuntimeException(e);
} else {
throw rteSupplier.get(e);
}
}
};
}
/**
* 接收一个可以转化成 cn.hutool.core.lang.func.VoidFunc1的Lambda表达式和一个RuntimeException当执行表达式抛出任何异常的时候都会转化成运行时异常
* 如此一来代码中就不用显示的try-catch转化成运行时异常
*
* @param expression Lambda表达式
* @param rteSupplier 转化运行时异常的表达式
* @param <P> 运行时传入的参数类型
* @return {@link VoidFunc1Rt}
*/
public static <P> VoidFunc1Rt<P> uncheck(final VoidFunc1<P> expression, final Supplier1<RuntimeException, Exception> rteSupplier) {
Objects.requireNonNull(expression, "expression can not be null");
return t -> {
try {
expression.call(t);
} catch (final Exception e) {
if (rteSupplier == null) {
throw new RuntimeException(e);
} else {
throw rteSupplier.get(e);
}
}
};
}
public interface FuncRt<P, R> extends Func<P, R> {
@SuppressWarnings("unchecked")
@Override
R call(P... parameters) throws RuntimeException;
}
public interface Func0Rt<R> extends Func0<R> {
@Override
R call() throws RuntimeException;
}
public interface Func1Rt<P, R> extends Func1<P, R> {
@Override
R call(P parameter) throws RuntimeException;
}
public interface VoidFuncRt<P> extends VoidFunc<P> {
@SuppressWarnings("unchecked")
@Override
void call(P... parameters) throws RuntimeException;
}
public interface VoidFunc0Rt extends VoidFunc0 {
@Override
void call() throws RuntimeException;
}
public interface VoidFunc1Rt<P> extends VoidFunc1<P> {
@Override
void call(P parameter) throws RuntimeException;
}
}

View File

@ -25,7 +25,7 @@
package cn.hutool.core.lang; package cn.hutool.core.lang;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.func.Func0; import cn.hutool.core.lang.func.SerSupplier;
import cn.hutool.core.text.StrUtil; import cn.hutool.core.text.StrUtil;
import java.util.Objects; import java.util.Objects;
@ -40,7 +40,7 @@ import java.util.stream.Stream;
/** /**
* 复制jdk16中的Optional以及自己进行了一点调整和新增比jdk8中的Optional多了几个实用的函数<br> * 复制jdk16中的Optional以及自己进行了一点调整和新增比jdk8中的Optional多了几个实用的函数<br>
* 详细见https://gitee.com/dromara/hutool/pulls/426 * 详细见<a href="https://gitee.com/dromara/hutool/pulls/426"></a>
* *
* @param <T> 包裹里元素的类型 * @param <T> 包裹里元素的类型
* @author VampireAchao * @author VampireAchao
@ -116,9 +116,9 @@ public class Opt<T> {
* @param <T> 类型 * @param <T> 类型
* @return 操作执行后的值 * @return 操作执行后的值
*/ */
public static <T> Opt<T> ofTry(final Func0<T> supplier) { public static <T> Opt<T> ofTry(final SerSupplier<T> supplier) {
try { try {
return Opt.ofNullable(supplier.call()); return Opt.ofNullable(supplier.getting());
} catch (final Exception e) { } catch (final Exception e) {
final Opt<T> empty = new Opt<>(null); final Opt<T> empty = new Opt<>(null);
empty.exception = e; empty.exception = e;
@ -181,7 +181,7 @@ public class Opt<T> {
/** /**
* 获取异常<br> * 获取异常<br>
* 当调用 {@link #ofTry(Func0)}异常信息不会抛出而是保存调用此方法获取抛出的异常 * 当调用 {@link #ofTry(SerSupplier)}异常信息不会抛出而是保存调用此方法获取抛出的异常
* *
* @return 异常 * @return 异常
* @since 5.7.17 * @since 5.7.17
@ -192,7 +192,7 @@ public class Opt<T> {
/** /**
* 是否失败<br> * 是否失败<br>
* 当调用 {@link #ofTry(Func0)}抛出异常则表示失败 * 当调用 {@link #ofTry(SerSupplier)}抛出异常则表示失败
* *
* @return 是否失败 * @return 是否失败
* @since 5.7.17 * @since 5.7.17

View File

@ -1,7 +1,7 @@
package cn.hutool.core.lang; package cn.hutool.core.lang;
import cn.hutool.core.classloader.ClassLoaderUtil; import cn.hutool.core.classloader.ClassLoaderUtil;
import cn.hutool.core.lang.func.Func0; import cn.hutool.core.lang.func.SerSupplier;
import cn.hutool.core.reflect.ConstructorUtil; import cn.hutool.core.reflect.ConstructorUtil;
import cn.hutool.core.text.StrUtil; import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
@ -51,14 +51,14 @@ public final class Singleton {
* @since 5.3.3 * @since 5.3.3
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T get(final String key, final Func0<T> supplier) { public static <T> T get(final String key, final SerSupplier<T> supplier) {
//return (T) POOL.computeIfAbsent(key, (k)-> supplier.callWithRuntimeException()); //return (T) POOL.computeIfAbsent(key, (k)-> supplier.callWithRuntimeException());
// issues#2349 // issues#2349
// ConcurrentHashMap.computeIfAbsent在某些情况下会导致死循环问题此处采用Dubbo的解决方案 // ConcurrentHashMap.computeIfAbsent在某些情况下会导致死循环问题此处采用Dubbo的解决方案
Object value = POOL.get(key); Object value = POOL.get(key);
if(null == value){ if (null == value) {
POOL.putIfAbsent(key, supplier.callWithRuntimeException()); POOL.putIfAbsent(key, supplier.get());
value = POOL.get(key); value = POOL.get(key);
} }
return (T) value; return (T) value;
@ -104,12 +104,12 @@ public final class Singleton {
/** /**
* 判断某个类的对象是否存在 * 判断某个类的对象是否存在
* *
* @param clazz * @param clazz
* @param params 构造参数 * @param params 构造参数
* @return 是否存在 * @return 是否存在
*/ */
public static boolean exists(final Class<?> clazz, final Object... params){ public static boolean exists(final Class<?> clazz, final Object... params) {
if (null != clazz){ if (null != clazz) {
final String key = buildKey(clazz.getName(), params); final String key = buildKey(clazz.getName(), params);
return POOL.containsKey(key); return POOL.containsKey(key);
} }
@ -121,7 +121,7 @@ public final class Singleton {
* *
* @return 非重复的类集合 * @return 非重复的类集合
*/ */
public static Set<Class<?>> getExistClass(){ public static Set<Class<?>> getExistClass() {
return POOL.values().stream().map(Object::getClass).collect(Collectors.toSet()); return POOL.values().stream().map(Object::getClass).collect(Collectors.toSet());
} }

View File

@ -1,23 +0,0 @@
package cn.hutool.core.lang.func;
/**
* 3参数Consumer
*
* @param <P1> 参数一类型
* @param <P2> 参数二类型
* @param <P3> 参数三类型
* @author TomXin
* @since 5.7.22
*/
@FunctionalInterface
public interface Consumer3<P1, P2, P3> {
/**
* 接收参数方法
*
* @param p1 参数一
* @param p2 参数二
* @param p3 参数三
*/
void accept(P1 p1, P2 p2, P3 p3);
}

View File

@ -1,43 +0,0 @@
package cn.hutool.core.lang.func;
import java.io.Serializable;
/**
* 函数对象<br>
* 接口灵感来自于<a href="http://actframework.org/">ActFramework</a><br>
* 一个函数接口代表一个一个函数用于包装一个函数为对象<br>
* 在JDK8之前Java的函数并不能作为参数传递也不能作为返回值存在此接口用于将一个函数包装成为一个对象从而传递对象
*
* @author Looly
*
* @param <P> 参数类型
* @param <R> 返回值类型
* @since 3.1.0
*/
@FunctionalInterface
public interface Func<P, R> extends Serializable {
/**
* 执行函数
*
* @param parameters 参数列表
* @return 函数执行结果
* @throws Exception 自定义异常
*/
@SuppressWarnings("unchecked")
R call(P... parameters) throws Exception;
/**
* 执行函数异常包装为RuntimeException
*
* @param parameters 参数列表
* @return 函数执行结果
*/
@SuppressWarnings("unchecked")
default R callWithRuntimeException(final P... parameters){
try {
return call(parameters);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,39 +0,0 @@
package cn.hutool.core.lang.func;
import java.io.Serializable;
/**
* 无参数的函数对象<br>
* 接口灵感来自于<a href="http://actframework.org/">ActFramework</a><br>
* 一个函数接口代表一个一个函数用于包装一个函数为对象<br>
* 在JDK8之前Java的函数并不能作为参数传递也不能作为返回值存在此接口用于将一个函数包装成为一个对象从而传递对象
*
* @author Looly
*
* @param <R> 返回值类型
* @since 4.5.2
*/
@FunctionalInterface
public interface Func0<R> extends Serializable {
/**
* 执行函数
*
* @return 函数执行结果
* @throws Exception 自定义异常
*/
R call() throws Exception;
/**
* 执行函数异常包装为RuntimeException
*
* @return 函数执行结果
* @since 5.3.6
*/
default R callWithRuntimeException(){
try {
return call();
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,43 +0,0 @@
package cn.hutool.core.lang.func;
import java.io.Serializable;
/**
* 只有一个参数的函数对象<br>
* 接口灵感来自于<a href="http://actframework.org/">ActFramework</a><br>
* 一个函数接口代表一个一个函数用于包装一个函数为对象<br>
* 在JDK8之前Java的函数并不能作为参数传递也不能作为返回值存在此接口用于将一个函数包装成为一个对象从而传递对象
*
* @author Looly
*
* @param <P> 参数类型
* @param <R> 返回值类型
* @since 4.2.2
*/
@FunctionalInterface
public interface Func1<P, R> extends Serializable {
/**
* 执行函数
*
* @param parameter 参数
* @return 函数执行结果
* @throws Exception 自定义异常
*/
R call(P parameter) throws Exception;
/**
* 执行函数异常包装为RuntimeException
*
* @param parameter 参数
* @return 函数执行结果
* @since 5.3.6
*/
default R callWithRuntimeException(final P parameter){
try {
return call(parameter);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,85 @@
package cn.hutool.core.lang.func;
import cn.hutool.core.exceptions.UtilException;
import java.io.Serializable;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.stream.Stream;
/**
* SerBiConsumer
*
* @author VampireAchao
*/
@FunctionalInterface
public interface SerBiConsumer<T, U> extends BiConsumer<T, U>, Serializable {
/**
* multi
*
* @param consumers lambda
* @param <T> type
* @param <U> return type
* @return lambda
*/
@SafeVarargs
static <T, U> SerBiConsumer<T, U> multi(SerBiConsumer<T, U>... consumers) {
return Stream.of(consumers).reduce(SerBiConsumer::andThen).orElseGet(() -> (o, q) -> {});
}
/**
* Performs this operation on the given arguments.
*
* @param t the first input argument
* @param u the second input argument
* @throws Exception wrappered checked exceptions for easy using
*/
@SuppressWarnings("all")
void accepting(T t, U u) throws Exception;
/**
* Performs this operation on the given arguments.
*
* @param t the first input argument
* @param u the second input argument
*/
@Override
default void accept(T t, U u) {
try {
accepting(t, u);
} catch (Exception e) {
throw new UtilException(e);
}
}
/**
* Returns a composed {@code SerBiCons} that performs, in sequence, this
* operation followed by the {@code after} operation. If performing either
* operation throws an exception, it is relayed to the caller of the
* composed operation. If performing this operation throws an exception,
* the {@code after} operation will not be performed.
*
* @param after the operation to perform after this operation
* @return a composed {@code SerBiCons} that performs in sequence this
* operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null
*/
default SerBiConsumer<T, U> andThen(SerBiConsumer<? super T, ? super U> after) {
Objects.requireNonNull(after);
return (l, r) -> {
accepting(l, r);
after.accepting(l, r);
};
}
/**
* 什么也不做用于一些需要传入lambda的方法占位使用
*
* @param <T> 参数1类型
* @param <U> 参数2类型
* @return 什么也不做
*/
static <T, U> SerBiConsumer<T, U> nothing() {
return (l, r) -> {};
}
}

View File

@ -0,0 +1,63 @@
package cn.hutool.core.lang.func;
import cn.hutool.core.exceptions.UtilException;
import java.io.Serializable;
import java.util.Objects;
import java.util.function.BiFunction;
/**
* SerBiFunction
*
* @author VampireAchao
* @since 2022/6/8
*/
@FunctionalInterface
public interface SerBiFunction<T, U, R> extends BiFunction<T, U, R>, Serializable {
/**
* Applies this function to the given arguments.
*
* @param t the first function argument
* @param u the second function argument
* @return the function result
* @throws Exception wrappered checked exceptions
*/
@SuppressWarnings("all")
R applying(T t, U u) throws Exception;
/**
* Applies this function to the given arguments.
*
* @param t the first function argument
* @param u the second function argument
* @return the function result
*/
@Override
default R apply(T t, U u) {
try {
return this.applying(t, u);
} catch (Exception e) {
throw new UtilException(e);
}
}
/**
* Returns a composed function that first applies this function to
* its input, and then applies the {@code after} function to the result.
* If evaluation of either function throws an exception, it is relayed to
* the caller of the composed function.
*
* @param <V> the type of output of the {@code after} function, and of the
* composed function
* @param after the function to apply after this function is applied
* @return a composed function that first applies this function and then
* applies the {@code after} function
* @throws NullPointerException if after is null
*/
default <V> SerBiFunction<T, U, V> andThen(SerFunction<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t, U u) -> after.apply(this.apply(t, u));
}
}

View File

@ -0,0 +1,103 @@
package cn.hutool.core.lang.func;
import cn.hutool.core.exceptions.UtilException;
import java.io.Serializable;
import java.util.Objects;
import java.util.function.BiPredicate;
/**
* SerBiPred
*
* @author VampireAchao
* @since 2022/6/8
*/
@FunctionalInterface
public interface SerBiPredicate<T, U> extends BiPredicate<T, U>, Serializable {
/**
* Evaluates this predicate on the given arguments.
*
* @param t the first input argument
* @param u the second input argument
* @return {@code true} if the input arguments match the predicate,
* otherwise {@code false}
* @throws Exception wrappered checked exceptions
*/
@SuppressWarnings("all")
boolean testing(T t, U u) throws Exception;
/**
* Evaluates this predicate on the given arguments.
*
* @param t the first input argument
* @param u the second input argument
* @return {@code true} if the input arguments match the predicate,
* otherwise {@code false}
*/
@Override
default boolean test(T t, U u) {
try {
return testing(t, u);
} catch (Exception e) {
throw new UtilException(e);
}
}
/**
* Returns a composed predicate that represents a short-circuiting logical
* AND of this predicate and another. When evaluating the composed
* predicate, if this predicate is {@code false}, then the {@code other}
* predicate is not evaluated.
*
* <p>Any exceptions thrown during evaluation of either predicate are relayed
* to the caller; if evaluation of this predicate throws an exception, the
* {@code other} predicate will not be evaluated.
*
* @param other a predicate that will be logically-ANDed with this
* predicate
* @return a composed predicate that represents the short-circuiting logical
* AND of this predicate and the {@code other} predicate
* @throws NullPointerException if other is null
*/
default SerBiPredicate<T, U> and(SerBiPredicate<? super T, ? super U> other) {
Objects.requireNonNull(other);
return (T t, U u) -> test(t, u) && other.test(t, u);
}
/**
* Returns a predicate that represents the logical negation of this
* predicate.
*
* @return a predicate that represents the logical negation of this
* predicate
*/
@Override
default SerBiPredicate<T, U> negate() {
return (T t, U u) -> !test(t, u);
}
/**
* Returns a composed predicate that represents a short-circuiting logical
* OR of this predicate and another. When evaluating the composed
* predicate, if this predicate is {@code true}, then the {@code other}
* predicate is not evaluated.
*
* <p>Any exceptions thrown during evaluation of either predicate are relayed
* to the caller; if evaluation of this predicate throws an exception, the
* {@code other} predicate will not be evaluated.
*
* @param other a predicate that will be logically-ORed with this
* predicate
* @return a composed predicate that represents the short-circuiting logical
* OR of this predicate and the {@code other} predicate
* @throws NullPointerException if other is null
*/
default SerBiPredicate<T, U> or(SerBiPredicate<? super T, ? super U> other) {
Objects.requireNonNull(other);
return (T t, U u) -> test(t, u) || other.test(t, u);
}
}

View File

@ -0,0 +1,96 @@
package cn.hutool.core.lang.func;
import cn.hutool.core.exceptions.UtilException;
import java.io.Serializable;
import java.util.Comparator;
import java.util.Objects;
import java.util.function.BinaryOperator;
/**
* SerBinaryOperator
*
* @author VampireAchao
* @since 2022/6/8
*/
@FunctionalInterface
public interface SerBinaryOperator<T> extends BinaryOperator<T>, Serializable {
/**
* Applies this function to the given arguments.
*
* @param t the first function argument
* @param u the second function argument
* @return the function result
* @throws Exception wrappered checked exceptions
*/
@SuppressWarnings("all")
T applying(T t, T u) throws Exception;
/**
* Applies this function to the given arguments.
*
* @param t the first function argument
* @param u the second function argument
* @return the function result
*/
@Override
default T apply(T t, T u) {
try {
return this.applying(t, u);
} catch (Exception e) {
throw new UtilException(e);
}
}
/**
* Returns a {@link SerBinaryOperator} which returns the lesser of two elements
* according to the specified {@code Comparator}.
*
* @param <T> the type of the input arguments of the comparator
* @param comparator a {@code Comparator} for comparing the two values
* @return a {@code SerBiUnOp} which returns the lesser of its operands,
* according to the supplied {@code Comparator}
* @throws NullPointerException if the argument is null
*/
static <T> SerBinaryOperator<T> minBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
}
/**
* Returns a {@link SerBinaryOperator} which returns the greater of two elements
* according to the specified {@code Comparator}.
*
* @param <T> the type of the input arguments of the comparator
* @param comparator a {@code Comparator} for comparing the two values
* @return a {@code SerBiUnOp} which returns the greater of its operands,
* according to the supplied {@code Comparator}
* @throws NullPointerException if the argument is null
*/
static <T> SerBinaryOperator<T> maxBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
}
/**
* just before
*
* @param <T> type
* @return before
*/
static <T> SerBinaryOperator<T> justBefore() {
return (l, r) -> l;
}
/**
* just after
*
* @param <T> type
* @return after
*/
static <T> SerBinaryOperator<T> justAfter() {
return (l, r) -> r;
}
}

View File

@ -0,0 +1,83 @@
package cn.hutool.core.lang.func;
import cn.hutool.core.exceptions.UtilException;
import java.io.Serializable;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.stream.Stream;
/**
* 可序列化的Consumer
*
* @author VampireAchao
* @see Consumer
*/
@FunctionalInterface
public interface SerConsumer<T> extends Consumer<T>, Serializable {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
* @throws Exception wrappered checked exceptions
*/
@SuppressWarnings("all")
void accepting(T t) throws Exception;
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
@Override
default void accept(T t) {
try {
accepting(t);
} catch (Exception e) {
throw new UtilException(e);
}
}
/**
* multi
*
* @param consumers lambda
* @param <T> type
* @return lambda
*/
@SafeVarargs
static <T> SerConsumer<T> multi(SerConsumer<T>... consumers) {
return Stream.of(consumers).reduce(SerConsumer::andThen).orElseGet(() -> o -> {});
}
/**
* Returns a composed {@code Consumer} that performs, in sequence, this
* operation followed by the {@code after} operation. If performing either
* operation throws an exception, it is relayed to the caller of the
* composed operation. If performing this operation throws an exception,
* the {@code after} operation will not be performed.
*
* @param after the operation to perform after this operation
* @return a composed {@code Consumer} that performs in sequence this
* operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null
*/
default SerConsumer<T> andThen(SerConsumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> {
accept(t);
after.accept(t);
};
}
/**
* nothing
*
* @param <T> type
* @return nothing
*/
static <T> SerConsumer<T> nothing() {
return t -> {};
}
}

View File

@ -0,0 +1,65 @@
package cn.hutool.core.lang.func;
import cn.hutool.core.exceptions.UtilException;
import java.io.Serializable;
import java.util.Objects;
/**
* 3参数Consumer
*
* @param <P1> 参数一类型
* @param <P2> 参数二类型
* @param <P3> 参数三类型
* @author TomXin, VampireAchao
* @since 5.7.22
*/
@FunctionalInterface
public interface SerConsumer3<P1, P2, P3> extends Serializable {
/**
* 接收参数方法
*
* @param p1 参数一
* @param p2 参数二
* @param p3 参数三
* @throws Exception wrappered checked exceptions
*/
@SuppressWarnings("all")
void accepting(P1 p1, P2 p2, P3 p3) throws Exception;
/**
* 接收参数方法
*
* @param p1 参数一
* @param p2 参数二
* @param p3 参数三
*/
default void accept(P1 p1, P2 p2, P3 p3) {
try {
accepting(p1, p2, p3);
} catch (Exception e) {
throw new UtilException(e);
}
}
/**
* Returns a composed {@code SerConsumer3} that performs, in sequence, this
* operation followed by the {@code after} operation. If performing either
* operation throws an exception, it is relayed to the caller of the
* composed operation. If performing this operation throws an exception,
* the {@code after} operation will not be performed.
*
* @param after the operation to perform after this operation
* @return a composed {@code SerConsumer3} that performs in sequence this
* operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null
*/
default SerConsumer3<P1, P2, P3> andThen(SerConsumer3<P1, P2, P3> after) {
Objects.requireNonNull(after);
return (P1 p1, P2 p2, P3 p3) -> {
accept(p1, p2, p3);
after.accept(p1, p2, p3);
};
}
}

View File

@ -0,0 +1,63 @@
package cn.hutool.core.lang.func;
import cn.hutool.core.exceptions.UtilException;
import java.io.Serializable;
import java.util.function.Function;
/**
* 可序列化的Function
*
* @author VampireAchao
* @see Function
*/
@FunctionalInterface
public interface SerFunction<T, R> extends Function<T, R>, Serializable {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
* @throws Exception wrappered checked exceptions
*/
@SuppressWarnings("all")
R applying(T t) throws Exception;
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
@Override
default R apply(T t) {
try {
return applying(t);
} catch (Exception e) {
throw new UtilException(e);
}
}
/**
* Returns a function that always returns its input argument.
*
* @param <T> the type of the input and output objects to the function
* @return a function that always returns its input argument
*/
static <T> SerFunction<T, T> identity() {
return t -> t;
}
/**
* casting identity
*
* @param <T> param type
* @param <R> result type
* @return identity after casting
*/
@SuppressWarnings("unchecked")
static <T, R> Function<T, R> castingIdentity() {
return t -> (R) t;
}
}

View File

@ -0,0 +1,139 @@
package cn.hutool.core.lang.func;
import cn.hutool.core.exceptions.UtilException;
import java.io.Serializable;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* 可序列化的Predicate
*
* @author VampireAchao
* @see Predicate
*/
@FunctionalInterface
public interface SerPredicate<T> extends Predicate<T>, Serializable {
/**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
* @throws Exception wrappered checked exceptions
*/
boolean testing(T t) throws Exception;
/**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
@Override
default boolean test(T t) {
try {
return testing(t);
} catch (Exception e) {
throw new UtilException(e);
}
}
/**
* multi
*
* @param predicates lambda
* @param <T> 类型
* @return lambda
*/
@SafeVarargs
static <T> SerPredicate<T> multiAnd(SerPredicate<T>... predicates) {
return Stream.of(predicates).reduce(SerPredicate::and).orElseGet(() -> o -> true);
}
/**
* multi
*
* @param predicates lambda
* @param <T> 类型
* @return lambda
*/
@SafeVarargs
static <T> SerPredicate<T> multiOr(SerPredicate<T>... predicates) {
return Stream.of(predicates).reduce(SerPredicate::or).orElseGet(() -> o -> false);
}
/**
* Returns a predicate that tests if two arguments are equal according
* to {@link Objects#equals(Object, Object)}.
*
* @param <T> the type of arguments to the predicate
* @param targetRef the object reference with which to compare for equality,
* which may be {@code null}
* @return a predicate that tests if two arguments are equal according
* to {@link Objects#equals(Object, Object)}
*/
static <T> SerPredicate<T> isEqual(Object... targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> Stream.of(targetRef).allMatch(target -> target.equals(object));
}
/**
* Returns a composed predicate that represents a short-circuiting logical
* AND of this predicate and another. When evaluating the composed
* predicate, if this predicate is {@code false}, then the {@code other}
* predicate is not evaluated.
*
* <p>Any exceptions thrown during evaluation of either predicate are relayed
* to the caller; if evaluation of this predicate throws an exception, the
* {@code other} predicate will not be evaluated.
*
* @param other a predicate that will be logically-ANDed with this
* predicate
* @return a composed predicate that represents the short-circuiting logical
* AND of this predicate and the {@code other} predicate
* @throws NullPointerException if other is null
*/
default SerPredicate<T> and(SerPredicate<? super T> other) {
Objects.requireNonNull(other);
return t -> test(t) && other.test(t);
}
/**
* Returns a predicate that represents the logical negation of this
* predicate.
*
* @return a predicate that represents the logical negation of this
* predicate
*/
@Override
default SerPredicate<T> negate() {
return t -> !test(t);
}
/**
* Returns a composed predicate that represents a short-circuiting logical
* OR of this predicate and another. When evaluating the composed
* predicate, if this predicate is {@code true}, then the {@code other}
* predicate is not evaluated.
*
* <p>Any exceptions thrown during evaluation of either predicate are relayed
* to the caller; if evaluation of this predicate throws an exception, the
* {@code other} predicate will not be evaluated.
*
* @param other a predicate that will be logically-ORed with this
* predicate
* @return a composed predicate that represents the short-circuiting logical
* OR of this predicate and the {@code other} predicate
* @throws NullPointerException if other is null
*/
default SerPredicate<T> or(SerPredicate<? super T> other) {
Objects.requireNonNull(other);
return t -> test(t) || other.test(t);
}
}

View File

@ -0,0 +1,63 @@
package cn.hutool.core.lang.func;
import cn.hutool.core.exceptions.UtilException;
import java.io.Serializable;
import java.util.stream.Stream;
/**
* 可序列化的Runnable
*
* @author VampireAchao
* @see Runnable
*/
@FunctionalInterface
public interface SerRunnable extends Runnable, Serializable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @throws Exception wrappered checked exceptions
* @see Thread#run()
*/
@SuppressWarnings("all")
void running() throws Exception;
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see Thread#run()
*/
@Override
default void run() {
try {
running();
} catch (Exception e) {
throw new UtilException(e);
}
}
/**
* multi
*
* @param serRunnableArray lambda
* @return lambda
*/
static SerRunnable multi(SerRunnable... serRunnableArray) {
return () -> Stream.of(serRunnableArray).forEach(SerRunnable::run);
}
}

View File

@ -0,0 +1,53 @@
package cn.hutool.core.lang.func;
import cn.hutool.core.exceptions.UtilException;
import java.io.Serializable;
import java.util.function.Supplier;
import java.util.stream.Stream;
/**
* 可序列化的Supplier
*
* @author VampireAchao
* @see Supplier
*/
@FunctionalInterface
public interface SerSupplier<T> extends Supplier<T>, Serializable {
/**
* Gets a result.
*
* @return a result
* @throws Exception wrappered checked exceptions
*/
@SuppressWarnings("all")
T getting() throws Exception;
/**
* Gets a result.
*
* @return a result
*/
@Override
default T get() {
try {
return getting();
} catch (Exception e) {
throw new UtilException(e);
}
}
/**
* last
*
* @param serSups lambda
* @param <T> type
* @return lambda
*/
@SafeVarargs
static <T> SerSupplier<T> last(SerSupplier<T>... serSups) {
return Stream.of(serSups).reduce((l, r) -> r).orElseGet(() -> () -> null);
}
}

View File

@ -0,0 +1,68 @@
package cn.hutool.core.lang.func;
import cn.hutool.core.exceptions.UtilException;
import java.io.Serializable;
import java.util.function.Function;
import java.util.function.UnaryOperator;
/**
* 可序列化的UnaryOperator
*
* @author VampireAchao
* @see UnaryOperator
*/
@FunctionalInterface
public interface SerUnaryOperator<T> extends UnaryOperator<T>, Serializable {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
* @throws Exception wrappered checked exceptions
*/
@SuppressWarnings("all")
T applying(T t) throws Exception;
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
@Override
default T apply(T t) {
try {
return applying(t);
} catch (Exception e) {
throw new UtilException(e);
}
}
/**
* Returns a unary operator that always returns its input argument.
*
* @param <T> the type of the input and output of the operator
* @return a unary operator that always returns its input argument
*/
static <T> SerUnaryOperator<T> identity() {
return t -> t;
}
/**
* casting identity
*
* @param function source function
* @param <T> param type
* @param <R> result type
* @param <F> lambda type
* @return identity after casting
*/
@SuppressWarnings("unchecked")
static <T, R, F extends Function<T, R>> SerUnaryOperator<T> casting(F function) {
return t -> (T) function.apply(t);
}
}

View File

@ -1,32 +0,0 @@
package cn.hutool.core.lang.func;
import java.util.function.Supplier;
/**
* 1参数Supplier
*
* @param <T> 目标 类型
* @param <P1> 参数一 类型
* @author TomXin
* @since 5.7.21
*/
@FunctionalInterface
public interface Supplier1<T, P1> {
/**
* 生成实例的方法
*
* @param p1 参数一
* @return 目标对象
*/
T get(P1 p1);
/**
* 将带有参数的Supplier转换为无参{@link Supplier}
*
* @param p1 参数1
* @return {@link Supplier}
*/
default Supplier<T> toSupplier(final P1 p1) {
return () -> get(p1);
}
}

View File

@ -1,36 +0,0 @@
package cn.hutool.core.lang.func;
import java.util.function.Supplier;
/**
* 两个参数的Supplier
*
* @param <T> 目标 类型
* @param <P1> 参数一 类型
* @param <P2> 参数二 类型
* @author TomXin
* @since 5.7.21
*/
@FunctionalInterface
public interface Supplier2<T, P1, P2> {
/**
* 生成实例的方法
*
* @param p1 参数一
* @param p2 参数二
* @return 目标对象
*/
T get(P1 p1, P2 p2);
/**
* 将带有参数的Supplier转换为无参{@link Supplier}
*
* @param p1 参数1
* @param p2 参数2
* @return {@link Supplier}
*/
default Supplier<T> toSupplier(final P1 p1, final P2 p2) {
return () -> get(p1, p2);
}
}

View File

@ -1,39 +0,0 @@
package cn.hutool.core.lang.func;
import java.util.function.Supplier;
/**
* 3参数Supplier
*
* @param <T> 目标类型
* @param <P1> 参数一类型
* @param <P2> 参数二类型
* @param <P3> 参数三类型
* @author TomXin
* @since 5.7.21
*/
@FunctionalInterface
public interface Supplier3<T, P1, P2, P3> {
/**
* 生成实例的方法
*
* @param p1 参数一
* @param p2 参数二
* @param p3 参数三
* @return 目标对象
*/
T get(P1 p1, P2 p2, P3 p3);
/**
* 将带有参数的Supplier转换为无参{@link Supplier}
*
* @param p1 参数1
* @param p2 参数2
* @param p3 参数3
* @return {@link Supplier}
*/
default Supplier<T> toSupplier(final P1 p1, final P2 p2, final P3 p3) {
return () -> get(p1, p2, p3);
}
}

View File

@ -1,42 +0,0 @@
package cn.hutool.core.lang.func;
import java.util.function.Supplier;
/**
* 4参数Supplier
*
* @param <T> 目标 类型
* @param <P1> 参数一 类型
* @param <P2> 参数二 类型
* @param <P3> 参数三 类型
* @param <P4> 参数四 类型
* @author TomXin
* @since 5.7.21
*/
@FunctionalInterface
public interface Supplier4<T, P1, P2, P3, P4> {
/**
* 生成实例的方法
*
* @param p1 参数一
* @param p2 参数二
* @param p3 参数三
* @param p4 参数四
* @return 目标对象
*/
T get(P1 p1, P2 p2, P3 p3, P4 p4);
/**
* 将带有参数的Supplier转换为无参{@link Supplier}
*
* @param p1 参数1
* @param p2 参数2
* @param p3 参数3
* @param p4 参数4
* @return {@link Supplier}
*/
default Supplier<T> toSupplier(final P1 p1, final P2 p2, final P3 p3, final P4 p4) {
return () -> get(p1, p2, p3, p4);
}
}

View File

@ -1,45 +0,0 @@
package cn.hutool.core.lang.func;
import java.util.function.Supplier;
/**
* 5参数Supplier
*
* @param <T> 目标 类型
* @param <P1> 参数一 类型
* @param <P2> 参数二 类型
* @param <P3> 参数三 类型
* @param <P4> 参数四 类型
* @param <P5> 参数五 类型
* @author TomXin
* @since 5.7.21
*/
@FunctionalInterface
public interface Supplier5<T, P1, P2, P3, P4, P5> {
/**
* 生成实例的方法
*
* @param p1 参数一
* @param p2 参数二
* @param p3 参数三
* @param p4 参数四
* @param p5 参数五
* @return 目标对象
*/
T get(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5);
/**
* 将带有参数的Supplier转换为无参{@link Supplier}
*
* @param p1 参数1
* @param p2 参数2
* @param p3 参数3
* @param p4 参数4
* @param p5 参数5
* @return {@link Supplier}
*/
default Supplier<T> toSupplier(final P1 p1, final P2 p2, final P3 p3, final P4 p4, final P5 p5) {
return () -> get(p1, p2, p3, p4, p5);
}
}

View File

@ -1,41 +0,0 @@
package cn.hutool.core.lang.func;
import java.io.Serializable;
/**
* 函数对象<br>
* 接口灵感来自于<a href="http://actframework.org/">ActFramework</a><br>
* 一个函数接口代表一个一个函数用于包装一个函数为对象<br>
* 在JDK8之前Java的函数并不能作为参数传递也不能作为返回值存在此接口用于将一个函数包装成为一个对象从而传递对象
*
* @author Looly
*
* @param <P> 参数类型
* @since 3.1.0
*/
@FunctionalInterface
public interface VoidFunc<P> extends Serializable {
/**
* 执行函数
*
* @param parameters 参数列表
* @throws Exception 自定义异常
*/
@SuppressWarnings("unchecked")
void call(P... parameters) throws Exception;
/**
* 执行函数异常包装为RuntimeException
*
* @param parameters 参数列表
*/
@SuppressWarnings("unchecked")
default void callWithRuntimeException(final P... parameters){
try {
call(parameters);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,37 +0,0 @@
package cn.hutool.core.lang.func;
import java.io.Serializable;
/**
* 函数对象<br>
* 接口灵感来自于<a href="http://actframework.org/">ActFramework</a><br>
* 一个函数接口代表一个一个函数用于包装一个函数为对象<br>
* 在JDK8之前Java的函数并不能作为参数传递也不能作为返回值存在此接口用于将一个函数包装成为一个对象从而传递对象
*
* @author Looly
*
* @since 3.2.3
*/
@FunctionalInterface
public interface VoidFunc0 extends Serializable {
/**
* 执行函数
*
* @throws Exception 自定义异常
*/
void call() throws Exception;
/**
* 执行函数异常包装为RuntimeException
*
* @since 5.3.6
*/
default void callWithRuntimeException(){
try {
call();
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,39 +0,0 @@
package cn.hutool.core.lang.func;
import java.io.Serializable;
/**
* 函数对象<br>
* 接口灵感来自于<a href="http://actframework.org/">ActFramework</a><br>
* 一个函数接口代表一个一个函数用于包装一个函数为对象<br>
* 在JDK8之前Java的函数并不能作为参数传递也不能作为返回值存在此接口用于将一个函数包装成为一个对象从而传递对象
*
* @author Looly
*
* @since 3.2.3
*/
@FunctionalInterface
public interface VoidFunc1<P> extends Serializable {
/**
* 执行函数
*
* @param parameter 参数
* @throws Exception 自定义异常
*/
void call(P parameter) throws Exception;
/**
* 执行函数异常包装为RuntimeException
*
* @param parameter 参数
* @since 5.3.6
*/
default void callWithRuntimeException(final P parameter){
try {
call(parameter);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -7,7 +7,7 @@ import cn.hutool.core.collection.SetUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.exceptions.CloneRuntimeException; import cn.hutool.core.exceptions.CloneRuntimeException;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.func.Func0; import cn.hutool.core.lang.func.SerSupplier;
import cn.hutool.core.lang.func.LambdaUtil; import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.lang.getter.BasicTypeGetter; import cn.hutool.core.lang.getter.BasicTypeGetter;
@ -581,7 +581,7 @@ public class Dict extends CustomKeyMap<String, Object> implements BasicTypeGette
@Override @Override
protected String customKey(Object key) { protected String customKey(Object key) {
if (this.caseInsensitive && null != key) { if (this.caseInsensitive && null != key) {
key = ((String)key).toLowerCase(); key = ((String) key).toLowerCase();
} }
return (String) key; return (String) key;
} }
@ -598,8 +598,8 @@ public class Dict extends CustomKeyMap<String, Object> implements BasicTypeGette
* @return this * @return this
* @since 5.7.23 * @since 5.7.23
*/ */
public Dict setFields(final Func0<?>... fields) { public Dict setFields(final SerSupplier<?>... fields) {
Arrays.stream(fields).forEach(f -> set(LambdaUtil.getFieldName(f), f.callWithRuntimeException())); Arrays.stream(fields).forEach(f -> set(LambdaUtil.getFieldName(f), f.get()));
return this; return this;
} }
} }

View File

@ -1,6 +1,6 @@
package cn.hutool.core.map.multi; package cn.hutool.core.map.multi;
import cn.hutool.core.lang.func.Func0; import cn.hutool.core.lang.func.SerSupplier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -22,17 +22,17 @@ public class CollectionValueMap<K, V> extends AbsCollValueMap<K, V> {
private static final long serialVersionUID = 9012989578038102983L; private static final long serialVersionUID = 9012989578038102983L;
private final Func0<Collection<V>> collFactory; private final SerSupplier<Collection<V>> collFactory;
// ------------------------------------------------------------------------- Constructor start // ------------------------------------------------------------------------- Constructor start
/** /**
* 创建一个多值映射集合基于{@code mapFactory}{@code collFactory}实现 * 创建一个多值映射集合基于{@code mapFactory}{@code collFactory}实现
* *
* @param mapFactory 生成集合的工厂方法 * @param mapFactory 生成集合的工厂方法
* @param collFactory 生成值集合的工厂方法 * @param collFactory 生成值集合的工厂方法
*/ */
public CollectionValueMap(Supplier<Map<K, Collection<V>>> mapFactory, Func0<Collection<V>> collFactory) { public CollectionValueMap(Supplier<Map<K, Collection<V>>> mapFactory, SerSupplier<Collection<V>> collFactory) {
super(mapFactory); super(mapFactory);
this.collFactory = collFactory; this.collFactory = collFactory;
} }
@ -42,7 +42,7 @@ public class CollectionValueMap<K, V> extends AbsCollValueMap<K, V> {
* *
* @param collFactory 生成值集合的工厂方法 * @param collFactory 生成值集合的工厂方法
*/ */
public CollectionValueMap(Func0<Collection<V>> collFactory) { public CollectionValueMap(SerSupplier<Collection<V>> collFactory) {
this.collFactory = collFactory; this.collFactory = collFactory;
} }
@ -67,6 +67,6 @@ public class CollectionValueMap<K, V> extends AbsCollValueMap<K, V> {
@Override @Override
protected Collection<V> createCollection() { protected Collection<V> createCollection() {
return collFactory.callWithRuntimeException(); return collFactory.get();
} }
} }

View File

@ -2,7 +2,7 @@ package cn.hutool.core.map.multi;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.Opt; import cn.hutool.core.lang.Opt;
import cn.hutool.core.lang.func.Consumer3; import cn.hutool.core.lang.func.SerConsumer3;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import java.util.ArrayList; import java.util.ArrayList;
@ -243,7 +243,7 @@ public interface Table<R, C, V> extends Iterable<Table.Cell<R, C, V>> {
* *
* @param consumer 单元格值处理器 * @param consumer 单元格值处理器
*/ */
default void forEach(final Consumer3<? super R, ? super C, ? super V> consumer) { default void forEach(final SerConsumer3<? super R, ? super C, ? super V> consumer) {
for (final Cell<R, C, V> cell : this) { for (final Cell<R, C, V> cell : this) {
consumer.accept(cell.getRowKey(), cell.getColumnKey(), cell.getValue()); consumer.accept(cell.getRowKey(), cell.getColumnKey(), cell.getValue());
} }

View File

@ -2,10 +2,9 @@ package cn.hutool.core.regex;
import cn.hutool.core.collection.SetUtil; import cn.hutool.core.collection.SetUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Validator; import cn.hutool.core.lang.Validator;
import cn.hutool.core.lang.func.Func1; import cn.hutool.core.lang.func.SerFunction;
import cn.hutool.core.lang.mutable.Mutable; import cn.hutool.core.lang.mutable.Mutable;
import cn.hutool.core.lang.mutable.MutableObj; import cn.hutool.core.lang.mutable.MutableObj;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
@ -216,7 +215,7 @@ public class ReUtil {
* @param pattern 编译后的正则模式 * @param pattern 编译后的正则模式
* @param content 被匹配的内容 * @param content 被匹配的内容
* @param withGroup0 是否包括分组0此分组表示全匹配的信息 * @param withGroup0 是否包括分组0此分组表示全匹配的信息
* @param findAll 是否查找所有匹配到的内容{@code false}表示只读取第一个匹配到的内容 * @param findAll 是否查找所有匹配到的内容{@code false}表示只读取第一个匹配到的内容
* @return 匹配后得到的字符串数组按照分组顺序依次列出未匹配到返回空列表任何一个参数为null返回null * @return 匹配后得到的字符串数组按照分组顺序依次列出未匹配到返回空列表任何一个参数为null返回null
* @since 4.0.13 * @since 4.0.13
*/ */
@ -234,7 +233,7 @@ public class ReUtil {
result.add(matcher.group(i)); result.add(matcher.group(i));
} }
if(false == findAll){ if (false == findAll) {
break; break;
} }
} }
@ -911,7 +910,7 @@ public class ReUtil {
* @return 替换后的文本 * @return 替换后的文本
* @since 4.2.2 * @since 4.2.2
*/ */
public static String replaceAll(final CharSequence str, final String regex, final Func1<Matcher, String> replaceFun) { public static String replaceAll(final CharSequence str, final String regex, final SerFunction<Matcher, String> replaceFun) {
return replaceAll(str, Pattern.compile(regex), replaceFun); return replaceAll(str, Pattern.compile(regex), replaceFun);
} }
@ -930,7 +929,7 @@ public class ReUtil {
* @return 替换后的字符串 * @return 替换后的字符串
* @since 4.2.2 * @since 4.2.2
*/ */
public static String replaceAll(final CharSequence str, final Pattern pattern, final Func1<Matcher, String> replaceFun) { public static String replaceAll(final CharSequence str, final Pattern pattern, final SerFunction<Matcher, String> replaceFun) {
if (StrUtil.isEmpty(str)) { if (StrUtil.isEmpty(str)) {
return StrUtil.str(str); return StrUtil.str(str);
} }
@ -938,11 +937,7 @@ public class ReUtil {
final Matcher matcher = pattern.matcher(str); final Matcher matcher = pattern.matcher(str);
final StringBuffer buffer = new StringBuffer(); final StringBuffer buffer = new StringBuffer();
while (matcher.find()) { while (matcher.find()) {
try { matcher.appendReplacement(buffer, replaceFun.apply(matcher));
matcher.appendReplacement(buffer, replaceFun.call(matcher));
} catch (final Exception e) {
throw new UtilException(e);
}
} }
matcher.appendTail(buffer); matcher.appendTail(buffer);
return buffer.toString(); return buffer.toString();

View File

@ -27,11 +27,13 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
* 根据键与值的集合创建键值对流若两集合在相同下标的位置找不到对应的键或值则使用{@code null}填充<br> * 根据键与值的集合创建键值对流若两集合在相同下标的位置找不到对应的键或值则使用{@code null}填充<br>
* 比如: {@code [1, 2, 3]}{@code [1, 2]}合并则得到{@code [{1=1}, {2=2}, {3=null}]} * 比如: {@code [1, 2, 3]}{@code [1, 2]}合并则得到{@code [{1=1}, {2=2}, {3=null}]}
* *
* @param <K> 键类型
* @param <V> 值类型
* @param keys 键集合 * @param keys 键集合
* @param values 值集合 * @param values 值集合
* @return {@link EntryStream}实例 * @return {@link EntryStream}实例
*/ */
public static <A, B> EntryStream<A, B> merge(Iterable<A> keys, Iterable<B> values) { public static <K, V> EntryStream<K, V> merge(Iterable<K> keys, Iterable<V> values) {
final boolean hasKeys = ObjUtil.isNotNull(keys); final boolean hasKeys = ObjUtil.isNotNull(keys);
final boolean hasValues = ObjUtil.isNotNull(values); final boolean hasValues = ObjUtil.isNotNull(values);
// 皆为空 // 皆为空
@ -47,13 +49,13 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
return of(values, v -> null, Function.identity()); return of(values, v -> null, Function.identity());
} }
// 皆不为空 // 皆不为空
final List<Map.Entry<A, B>> entries = new ArrayList<>(); final List<Map.Entry<K, V>> entries = new ArrayList<>();
final Iterator<A> keyItr = keys.iterator(); final Iterator<K> keyItr = keys.iterator();
final Iterator<B> valueItr = values.iterator(); final Iterator<V> valueItr = values.iterator();
while (keyItr.hasNext() || valueItr.hasNext()) { while (keyItr.hasNext() || valueItr.hasNext()) {
entries.add(new Entry<>( entries.add(new Entry<>(
keyItr.hasNext() ? keyItr.next() : null, keyItr.hasNext() ? keyItr.next() : null,
valueItr.hasNext() ? valueItr.next() : null valueItr.hasNext() ? valueItr.next() : null
)); ));
} }
return of(entries); return of(entries);
@ -64,13 +66,13 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
* 对流的操作不会影响到入参的{@code map}实例本身 * 对流的操作不会影响到入参的{@code map}实例本身
* *
* @param map 集合 * @param map 集合
* @param <A> 键类型 * @param <K> 键类型
* @param <B> 值类型 * @param <V> 值类型
* @return {@link EntryStream}实例 * @return {@link EntryStream}实例
*/ */
public static <A, B> EntryStream<A, B> of(Map<A, B> map) { public static <K, V> EntryStream<K, V> of(Map<K, V> map) {
return ObjUtil.isNull(map) ? return ObjUtil.isNull(map) ?
empty() : of(map.entrySet()); empty() : of(map.entrySet());
} }
/** /**
@ -79,13 +81,13 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
* 若输入流中存在元素为{@code null}则会映射为一个键值皆为{@code null}的键值对 * 若输入流中存在元素为{@code null}则会映射为一个键值皆为{@code null}的键值对
* *
* @param entries {@link Iterable}实例 * @param entries {@link Iterable}实例
* @param <A> 键类型 * @param <K> 键类型
* @param <B> 值类型 * @param <V> 值类型
* @return {@link EntryStream}实例 * @return {@link EntryStream}实例
*/ */
public static <A, B> EntryStream<A, B> of(Iterable<? extends Map.Entry<A, B>> entries) { public static <K, V> EntryStream<K, V> of(Iterable<? extends Map.Entry<K, V>> entries) {
return ObjUtil.isNull(entries) ? return ObjUtil.isNull(entries) ?
empty() : of(StreamSupport.stream(entries.spliterator(), false)); empty() : of(StreamSupport.stream(entries.spliterator(), false));
} }
/** /**
@ -94,19 +96,20 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
* @param source 原始集合 * @param source 原始集合
* @param keyMapper 键的映射方法 * @param keyMapper 键的映射方法
* @param valueMapper 值的映射方法 * @param valueMapper 值的映射方法
* @param <A> 键类型 * @param <T> 元素类型
* @param <B> 值类型 * @param <K> 键类型
* @param <V> 值类型
* @return {@link EntryStream}实例 * @return {@link EntryStream}实例
*/ */
public static <T, A, B> EntryStream<A, B> of( public static <T, K, V> EntryStream<K, V> of(
Iterable<T> source, Function<? super T, ? extends A> keyMapper, Function<? super T, ? extends B> valueMapper) { Iterable<T> source, Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends V> valueMapper) {
Objects.requireNonNull(keyMapper); Objects.requireNonNull(keyMapper);
Objects.requireNonNull(valueMapper); Objects.requireNonNull(valueMapper);
if (ObjUtil.isNull(source)) { if (ObjUtil.isNull(source)) {
return empty(); return empty();
} }
final Stream<Map.Entry<A, B>> stream = StreamSupport.stream(source.spliterator(), false) final Stream<Map.Entry<K, V>> stream = StreamSupport.stream(source.spliterator(), false)
.map(t -> new Entry<>(keyMapper.apply(t), valueMapper.apply(t))); .map(t -> new Entry<>(keyMapper.apply(t), valueMapper.apply(t)));
return new EntryStream<>(stream); return new EntryStream<>(stream);
} }
@ -115,23 +118,23 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
* 若输入流中存在元素为{@code null}则会映射为一个键值皆为{@code null}的键值对 * 若输入流中存在元素为{@code null}则会映射为一个键值皆为{@code null}的键值对
* *
* @param stream * @param stream
* @param <A> 键类型 * @param <K> 键类型
* @param <B> 值类型 * @param <V> 值类型
* @return {@link EntryStream}实例 * @return {@link EntryStream}实例
*/ */
public static <A, B> EntryStream<A, B> of(Stream<? extends Map.Entry<A, B>> stream) { public static <K, V> EntryStream<K, V> of(Stream<? extends Map.Entry<K, V>> stream) {
return ObjUtil.isNull(stream) ? return ObjUtil.isNull(stream) ?
empty() : new EntryStream<>(stream.map(Entry::new)); empty() : new EntryStream<>(stream.map(Entry::new));
} }
/** /**
* 创建一个空的串行流 * 创建一个空的串行流
* *
* @param <A> 键类型 * @param <K> 键类型
* @param <B> 值类型 * @param <V> 值类型
* @return {@link EntryStream}实例 * @return {@link EntryStream}实例
*/ */
public static <A, B> EntryStream<A, B> empty() { public static <K, V> EntryStream<K, V> empty() {
return new EntryStream<>(Stream.empty()); return new EntryStream<>(Stream.empty());
} }
@ -336,7 +339,7 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
public <N> EntryStream<N, V> mapKeys(Function<? super K, ? extends N> mapper) { public <N> EntryStream<N, V> mapKeys(Function<? super K, ? extends N> mapper) {
Objects.requireNonNull(mapper); Objects.requireNonNull(mapper);
return new EntryStream<>( return new EntryStream<>(
stream.map(e -> new Entry<>(mapper.apply(e.getKey()), e.getValue())) stream.map(e -> new Entry<>(mapper.apply(e.getKey()), e.getValue()))
); );
} }
@ -350,7 +353,7 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
public <N> EntryStream<K, N> mapValues(Function<? super V, ? extends N> mapper) { public <N> EntryStream<K, N> mapValues(Function<? super V, ? extends N> mapper) {
Objects.requireNonNull(mapper); Objects.requireNonNull(mapper);
return new EntryStream<>( return new EntryStream<>(
stream.map(e -> new Entry<>(e.getKey(), mapper.apply(e.getValue()))) stream.map(e -> new Entry<>(e.getKey(), mapper.apply(e.getValue())))
); );
} }
@ -415,10 +418,10 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
public <N> EntryStream<N, V> flatMapKey(Function<? super K, Stream<? extends N>> keyMapper) { public <N> EntryStream<N, V> flatMapKey(Function<? super K, Stream<? extends N>> keyMapper) {
Objects.requireNonNull(keyMapper); Objects.requireNonNull(keyMapper);
return new EntryStream<>( return new EntryStream<>(
stream.flatMap(e -> keyMapper stream.flatMap(e -> keyMapper
.apply(e.getKey()) .apply(e.getKey())
.map(newKey -> new Entry<>(newKey, e.getValue())) .map(newKey -> new Entry<>(newKey, e.getValue()))
) )
); );
} }
@ -439,10 +442,10 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
public <N> EntryStream<K, N> flatMapValue(Function<? super V, Stream<? extends N>> valueMapper) { public <N> EntryStream<K, N> flatMapValue(Function<? super V, Stream<? extends N>> valueMapper) {
Objects.requireNonNull(valueMapper); Objects.requireNonNull(valueMapper);
return new EntryStream<>( return new EntryStream<>(
stream.flatMap(e -> valueMapper stream.flatMap(e -> valueMapper
.apply(e.getValue()) .apply(e.getValue())
.map(newVal -> new Entry<>(e.getKey(), newVal)) .map(newVal -> new Entry<>(e.getKey(), newVal))
) )
); );
} }
@ -478,8 +481,8 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
* 转为{@link HashMap}集合 * 转为{@link HashMap}集合
* *
* @return 集合 * @return 集合
* @see Collectors#toMap(Function, Function)
* @throws IllegalArgumentException 当键重复时抛出 * @throws IllegalArgumentException 当键重复时抛出
* @see Collectors#toMap(Function, Function)
*/ */
public Map<K, V> toMap() { public Map<K, V> toMap() {
return super.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); return super.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
@ -496,14 +499,14 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
* @see Collectors#groupingBy(Function, Supplier, Collector) * @see Collectors#groupingBy(Function, Supplier, Collector)
*/ */
public <N> Table<N, K, V> toTable( public <N> Table<N, K, V> toTable(
BiFunction<? super K, ? super V, ? extends N> rowKeyMapper, Supplier<Map<K, V>> colMapFactory, BinaryOperator<V> operator) { BiFunction<? super K, ? super V, ? extends N> rowKeyMapper, Supplier<Map<K, V>> colMapFactory, BinaryOperator<V> operator) {
Objects.requireNonNull(rowKeyMapper); Objects.requireNonNull(rowKeyMapper);
Objects.requireNonNull(colMapFactory); Objects.requireNonNull(colMapFactory);
Objects.requireNonNull(operator); Objects.requireNonNull(operator);
final Map<N, Map<K, V>> rawMap = collect(Collectors.groupingBy( final Map<N, Map<K, V>> rawMap = collect(Collectors.groupingBy(
e -> rowKeyMapper.apply(e.getKey(), e.getValue()), e -> rowKeyMapper.apply(e.getKey(), e.getValue()),
HashMap::new, HashMap::new,
Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, operator, colMapFactory) Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, operator, colMapFactory)
)); ));
return new RowKeyTable<>(rawMap, colMapFactory::get); return new RowKeyTable<>(rawMap, colMapFactory::get);
} }
@ -530,7 +533,7 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
* @return 集合 * @return 集合
*/ */
public <N> Table<N, K, V> toTableByKey( public <N> Table<N, K, V> toTableByKey(
Function<? super K, ? extends N> rowKeyMapper, Supplier<Map<K, V>> colMapFactory, BinaryOperator<V> operator) { Function<? super K, ? extends N> rowKeyMapper, Supplier<Map<K, V>> colMapFactory, BinaryOperator<V> operator) {
return toTable((k, v) -> rowKeyMapper.apply(k), colMapFactory, operator); return toTable((k, v) -> rowKeyMapper.apply(k), colMapFactory, operator);
} }
@ -556,7 +559,7 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
* @return 集合 * @return 集合
*/ */
public <N> Table<N, K, V> toTableByValue( public <N> Table<N, K, V> toTableByValue(
Function<? super V, ? extends N> rowKeyMapper, Supplier<Map<K, V>> colMapFactory, BinaryOperator<V> operator) { Function<? super V, ? extends N> rowKeyMapper, Supplier<Map<K, V>> colMapFactory, BinaryOperator<V> operator) {
return toTable((k, v) -> rowKeyMapper.apply(v), colMapFactory, operator); return toTable((k, v) -> rowKeyMapper.apply(v), colMapFactory, operator);
} }
@ -589,7 +592,7 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
* @return 集合 * @return 集合
*/ */
public <C extends Collection<V>> Map<K, C> groupByKey(Collector<V, ?, C> collector) { public <C extends Collection<V>> Map<K, C> groupByKey(Collector<V, ?, C> collector) {
return groupByKey((Supplier<Map<K,C>>)HashMap::new, collector); return groupByKey((Supplier<Map<K, C>>) HashMap::new, collector);
} }
/** /**
@ -597,14 +600,14 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
* *
* @param mapFactory 创建map集合的工厂方法 * @param mapFactory 创建map集合的工厂方法
* @param collector 对具有相同键的值的收集器 * @param collector 对具有相同键的值的收集器
* @param <C> 值集合的类型 * @param <C> 值集合的类型
* @param <M> 返回的map集合类型 * @param <M> 返回的map集合类型
* @return 集合 * @return 集合
*/ */
public <C extends Collection<V>, M extends Map<K, C>> M groupByKey(Supplier<M> mapFactory, Collector<V, ?, C> collector) { public <C extends Collection<V>, M extends Map<K, C>> M groupByKey(Supplier<M> mapFactory, Collector<V, ?, C> collector) {
return super.collect(Collectors.groupingBy( return super.collect(Collectors.groupingBy(
Map.Entry::getKey, mapFactory, Map.Entry::getKey, mapFactory,
CollectorUtil.transform(ArrayList::new, s -> s.stream().map(Map.Entry::getValue).collect(collector)) CollectorUtil.transform(ArrayList::new, s -> s.stream().map(Map.Entry::getValue).collect(collector))
)); ));
} }
@ -625,7 +628,7 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
*/ */
public EntryStream<V, K> inverse() { public EntryStream<V, K> inverse() {
return new EntryStream<>( return new EntryStream<>(
stream.map(e -> new Entry<>(e.getValue(), e.getKey())) stream.map(e -> new Entry<>(e.getValue(), e.getKey()))
); );
} }
@ -768,7 +771,7 @@ public class EntryStream<K, V> extends StreamWrapper<Map.Entry<K, V>, EntryStrea
* key重复时直接抛出异常 * key重复时直接抛出异常
*/ */
private static <T> BinaryOperator<T> throwingMerger() { private static <T> BinaryOperator<T> throwingMerger() {
return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); }; return (u, v) -> {throw new IllegalStateException(String.format("Duplicate key %s", u));};
} }
} }

View File

@ -4,7 +4,7 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.comparator.VersionComparator; import cn.hutool.core.comparator.VersionComparator;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.func.Func1; import cn.hutool.core.lang.func.SerFunction;
import cn.hutool.core.math.NumberUtil; import cn.hutool.core.math.NumberUtil;
import cn.hutool.core.regex.ReUtil; import cn.hutool.core.regex.ReUtil;
import cn.hutool.core.text.finder.CharFinder; import cn.hutool.core.text.finder.CharFinder;
@ -3430,10 +3430,10 @@ public class CharSequenceUtil extends StrChecker {
* @param pattern 用于匹配的正则式 * @param pattern 用于匹配的正则式
* @param replaceFun 决定如何替换的函数 * @param replaceFun 决定如何替换的函数
* @return 替换后的字符串 * @return 替换后的字符串
* @see ReUtil#replaceAll(CharSequence, java.util.regex.Pattern, Func1) * @see ReUtil#replaceAll(CharSequence, java.util.regex.Pattern, SerFunction)
* @since 4.2.2 * @since 4.2.2
*/ */
public static String replace(final CharSequence str, final java.util.regex.Pattern pattern, final Func1<java.util.regex.Matcher, String> replaceFun) { public static String replace(final CharSequence str, final java.util.regex.Pattern pattern, final SerFunction<java.util.regex.Matcher, String> replaceFun) {
return ReUtil.replaceAll(str, pattern, replaceFun); return ReUtil.replaceAll(str, pattern, replaceFun);
} }
@ -3444,10 +3444,10 @@ public class CharSequenceUtil extends StrChecker {
* @param regex 用于匹配的正则式 * @param regex 用于匹配的正则式
* @param replaceFun 决定如何替换的函数 * @param replaceFun 决定如何替换的函数
* @return 替换后的字符串 * @return 替换后的字符串
* @see ReUtil#replaceAll(CharSequence, String, Func1) * @see ReUtil#replaceAll(CharSequence, String, SerFunction)
* @since 4.2.2 * @since 4.2.2
*/ */
public static String replace(final CharSequence str, final String regex, final Func1<java.util.regex.Matcher, String> replaceFun) { public static String replace(final CharSequence str, final String regex, final SerFunction<java.util.regex.Matcher, String> replaceFun) {
return ReUtil.replaceAll(str, regex, replaceFun); return ReUtil.replaceAll(str, regex, replaceFun);
} }

View File

@ -1,8 +1,8 @@
package cn.hutool.core.util; package cn.hutool.core.util;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.lang.func.LambdaUtil; import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.lang.func.SerFunction;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.reflect.FieldUtil; import cn.hutool.core.reflect.FieldUtil;
import cn.hutool.core.text.StrUtil; import cn.hutool.core.text.StrUtil;
@ -240,12 +240,12 @@ public class EnumUtil {
* @param <C> 字段类型 * @param <C> 字段类型
* @return 对应枚举 获取不到时为 {@code null} * @return 对应枚举 获取不到时为 {@code null}
*/ */
public static <E extends Enum<E>, C> E getBy(final Func1<E, C> condition, final C value) { public static <E extends Enum<E>, C> E getBy(final SerFunction<E, C> condition, final C value) {
Class<E> implClass = LambdaUtil.getRealClass(condition); Class<E> implClass = LambdaUtil.getRealClass(condition);
if (Enum.class.equals(implClass)) { if (Enum.class.equals(implClass)) {
implClass = LambdaUtil.getRealClass(condition); implClass = LambdaUtil.getRealClass(condition);
} }
return Arrays.stream(implClass.getEnumConstants()).filter(e -> condition.callWithRuntimeException(e).equals(value)).findAny().orElse(null); return Arrays.stream(implClass.getEnumConstants()).filter(e -> condition.apply(e).equals(value)).findAny().orElse(null);
} }
/** /**
@ -260,7 +260,7 @@ public class EnumUtil {
* @return 对应枚举中另一字段值 获取不到时为 {@code null} * @return 对应枚举中另一字段值 获取不到时为 {@code null}
* @since 5.8.0 * @since 5.8.0
*/ */
public static <E extends Enum<E>, F, C> F getFieldBy(final Func1<E, F> field, public static <E extends Enum<E>, F, C> F getFieldBy(final SerFunction<E, F> field,
final Function<E, C> condition, final C value) { final Function<E, C> condition, final C value) {
Class<E> implClass = LambdaUtil.getRealClass(field); Class<E> implClass = LambdaUtil.getRealClass(field);
if (Enum.class.equals(implClass)) { if (Enum.class.equals(implClass)) {
@ -270,7 +270,7 @@ public class EnumUtil {
// 过滤 // 过滤
.filter(e -> condition.apply(e).equals(value)) .filter(e -> condition.apply(e).equals(value))
// 获取第一个并转换为结果 // 获取第一个并转换为结果
.findFirst().map(field::callWithRuntimeException).orElse(null); .findFirst().map(field).orElse(null);
} }
/** /**

View File

@ -52,7 +52,7 @@ public class GenericBuilderTest {
// 多参数构造 // 多参数构造
final Box box1 = GenericBuilder final Box box1 = GenericBuilder
.of(Box::new, 2048L, "Hello Partner!", 222, 333, 444) .of(() -> new Box(2048L, "Hello Partner!", 222, 333, 444))
.with(Box::alis) .with(Box::alis)
.build(); .build();
@ -65,10 +65,10 @@ public class GenericBuilderTest {
} }
@Test @Test
public void buildMapTest(){ public void buildMapTest() {
//Map创建 //Map创建
final HashMap<String, String> colorMap = GenericBuilder final HashMap<String, String> colorMap = GenericBuilder
.of(HashMap<String,String>::new) .of(HashMap<String, String>::new)
.with(Map::put, "red", "#FF0000") .with(Map::put, "red", "#FF0000")
.with(Map::put, "yellow", "#FFFF00") .with(Map::put, "yellow", "#FFFF00")
.with(Map::put, "blue", "#0000FF") .with(Map::put, "blue", "#0000FF")

View File

@ -1,62 +0,0 @@
package cn.hutool.core.exceptions;
import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.lang.func.VoidFunc0;
import org.junit.Assert;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
/**
* 方便的执行会抛出受检查类型异常的方法调用或者代码段
* <p>
* 该工具通过函数式的方式将那些需要抛出受检查异常的表达式或者代码段转化成一个标准的java8 functional 对象
* </p>
*
* @author conder
*/
public class CheckedUtilTest {
@Test
public void sleepTest() {
final VoidFunc0 func = () -> Thread.sleep(1000L);
func.callWithRuntimeException();
}
@SuppressWarnings("ConstantConditions")
@Test
public void supplierTest() {
final File noFile = new File("./no-file");
try {
//本行代码原本需要抛出受检查异常现在只抛出运行时异常
CheckedUtil.uncheck(() -> new FileInputStream(noFile)).call();
} catch (final Exception re) {
Assert.assertTrue(re instanceof RuntimeException);
}
}
@Test
public void functionTest() {
final Func1<String, String> afunc = (funcParam) -> {
if (funcParam.length() > 5) {
throw new Exception("这是受检查异常需要屌用处显示处理");
}
return funcParam.toUpperCase();
};
//afunc.apply("hello world"); 直接调用需要处理异常
try {
//本行代码原本需要抛出受检查异常现在只抛出运行时异常
CheckedUtil.uncheck(afunc).call("hello world");
} catch (final Exception re) {
Assert.assertTrue(re instanceof RuntimeException);
}
}
}

View File

@ -14,14 +14,14 @@ public class LambdaUtilTest {
@Test @Test
public void getMethodNameTest() { public void getMethodNameTest() {
final Func1<MyTeacher, String> lambda = MyTeacher::getAge; final SerFunction<MyTeacher, String> lambda = MyTeacher::getAge;
final String methodName = LambdaUtil.getMethodName(lambda); final String methodName = LambdaUtil.getMethodName(lambda);
Assert.assertEquals("getAge", methodName); Assert.assertEquals("getAge", methodName);
} }
@Test @Test
public void getFieldNameTest() { public void getFieldNameTest() {
final Func1<MyTeacher, String> lambda = MyTeacher::getAge; final SerFunction<MyTeacher, String> lambda = MyTeacher::getAge;
final String fieldName = LambdaUtil.getFieldName(lambda); final String fieldName = LambdaUtil.getFieldName(lambda);
Assert.assertEquals("age", fieldName); Assert.assertEquals("age", fieldName);
} }
@ -30,31 +30,31 @@ public class LambdaUtilTest {
public <T> void resolveTest() { public <T> void resolveTest() {
Stream.<Runnable>of(() -> { Stream.<Runnable>of(() -> {
// 引用构造函数 // 引用构造函数
final Func0<MyTeacher> lambda = MyTeacher::new; final SerSupplier<MyTeacher> lambda = MyTeacher::new;
final LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda); final LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
Assert.assertEquals(0, lambdaInfo.getParameterTypes().length); Assert.assertEquals(0, lambdaInfo.getParameterTypes().length);
Assert.assertEquals(MyTeacher.class, lambdaInfo.getReturnType()); Assert.assertEquals(MyTeacher.class, lambdaInfo.getReturnType());
}, () -> { }, () -> {
// 数组构造函数引用(此处数组构造参数) // 数组构造函数引用(此处数组构造参数)
final Func1<Integer, MyTeacher[]> lambda = MyTeacher[]::new; final SerFunction<Integer, MyTeacher[]> lambda = MyTeacher[]::new;
final LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda); final LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
Assert.assertEquals(int.class, lambdaInfo.getParameterTypes()[0]); Assert.assertEquals(int.class, lambdaInfo.getParameterTypes()[0]);
Assert.assertEquals(MyTeacher[].class, lambdaInfo.getReturnType()); Assert.assertEquals(MyTeacher[].class, lambdaInfo.getReturnType());
}, () -> { }, () -> {
// 引用静态方法 // 引用静态方法
final Func0<String> lambda = MyTeacher::takeAge; final SerSupplier<String> lambda = MyTeacher::takeAge;
final LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda); final LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
Assert.assertEquals(0, lambdaInfo.getParameterTypes().length); Assert.assertEquals(0, lambdaInfo.getParameterTypes().length);
Assert.assertEquals(String.class, lambdaInfo.getReturnType()); Assert.assertEquals(String.class, lambdaInfo.getReturnType());
}, () -> { }, () -> {
// 引用特定对象的实例方法 // 引用特定对象的实例方法
final Func0<String> lambda = new MyTeacher()::getAge; final SerSupplier<String> lambda = new MyTeacher()::getAge;
final LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda); final LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
Assert.assertEquals(0, lambdaInfo.getParameterTypes().length); Assert.assertEquals(0, lambdaInfo.getParameterTypes().length);
Assert.assertEquals(String.class, lambdaInfo.getReturnType()); Assert.assertEquals(String.class, lambdaInfo.getReturnType());
}, () -> { }, () -> {
// 引用特定类型的任意对象的实例方法 // 引用特定类型的任意对象的实例方法
final Func1<MyTeacher, String> lambda = MyTeacher::getAge; final SerFunction<MyTeacher, String> lambda = MyTeacher::getAge;
final LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda); final LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
Assert.assertEquals(0, lambdaInfo.getParameterTypes().length); Assert.assertEquals(0, lambdaInfo.getParameterTypes().length);
Assert.assertEquals(String.class, lambdaInfo.getReturnType()); Assert.assertEquals(String.class, lambdaInfo.getReturnType());
@ -80,15 +80,15 @@ public class LambdaUtilTest {
Assert.assertEquals(void.class, lambdaInfo.getReturnType()); Assert.assertEquals(void.class, lambdaInfo.getReturnType());
}, () -> { }, () -> {
// 一些特殊的lambda // 一些特殊的lambda
Assert.assertEquals("T[]", LambdaUtil.<Func<Object, Stream<?>>>resolve(Stream::of).getParameterTypes()[0].getTypeName()); Assert.assertEquals("T", LambdaUtil.<SerFunction<Object, Stream<?>>>resolve(Stream::of).getParameterTypes()[0].getTypeName());
Assert.assertEquals(MyTeacher[][].class, LambdaUtil.<Func1<Integer, MyTeacher[][]>>resolve(MyTeacher[][]::new).getReturnType()); Assert.assertEquals(MyTeacher[][].class, LambdaUtil.<SerFunction<Integer, MyTeacher[][]>>resolve(MyTeacher[][]::new).getReturnType());
Assert.assertEquals(Integer[][][].class, LambdaUtil.<VoidFunc1<Integer[][][]>>resolve(a -> {}).getParameterTypes()[0]); Assert.assertEquals(Integer[][][].class, LambdaUtil.<SerConsumer<Integer[][][]>>resolve(a -> {}).getParameterTypes()[0]);
Assert.assertEquals(Integer[][][].class, LambdaUtil.resolve((Serializable & Consumer3<Integer[][][], Integer[][], Integer>) (a, b, c) -> {}).getParameterTypes()[0]); Assert.assertEquals(Integer[][][].class, LambdaUtil.resolve((Serializable & SerConsumer3<Integer[][][], Integer[][], Integer>) (a, b, c) -> {}).getParameterTypes()[0]);
}).forEach(Runnable::run); }).forEach(Runnable::run);
} }
interface SerThiCons<P1, P2, P3> extends Consumer3<P1, P2, P3>, Serializable { interface SerThiCons<P1, P2, P3> extends SerConsumer3<P1, P2, P3>, Serializable {
} }
@Test @Test
@ -96,48 +96,48 @@ public class LambdaUtilTest {
final MyTeacher myTeacher = new MyTeacher(); final MyTeacher myTeacher = new MyTeacher();
Stream.<Runnable>of(() -> { Stream.<Runnable>of(() -> {
// 引用特定类型的任意对象的实例方法 // 引用特定类型的任意对象的实例方法
final Func1<MyTeacher, String> lambda = MyTeacher::getAge; final SerFunction<MyTeacher, String> lambda = MyTeacher::getAge;
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda)); Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
}, () -> { }, () -> {
// 枚举测试不会导致类型擦除 // 枚举测试不会导致类型擦除
final Func1<LambdaKindEnum, Integer> lambda = LambdaKindEnum::ordinal; final SerFunction<LambdaKindEnum, Integer> lambda = LambdaKindEnum::ordinal;
Assert.assertEquals(LambdaKindEnum.class, LambdaUtil.getRealClass(lambda)); Assert.assertEquals(LambdaKindEnum.class, LambdaUtil.getRealClass(lambda));
}, () -> { }, () -> {
// 调用父类方法能获取到正确的子类类型 // 调用父类方法能获取到正确的子类类型
final Func1<MyTeacher, ?> lambda = MyTeacher::getId; final SerFunction<MyTeacher, ?> lambda = MyTeacher::getId;
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda)); Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
}, () -> { }, () -> {
// 引用特定对象的实例方法 // 引用特定对象的实例方法
final Func0<String> lambda = myTeacher::getAge; final SerSupplier<String> lambda = myTeacher::getAge;
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda)); Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
}, () -> { }, () -> {
// 枚举测试只能获取到枚举类型 // 枚举测试只能获取到枚举类型
final Func0<Integer> lambda = LambdaKindEnum.REF_NONE::ordinal; final SerSupplier<Integer> lambda = LambdaKindEnum.REF_NONE::ordinal;
Assert.assertEquals(Enum.class, LambdaUtil.getRealClass(lambda)); Assert.assertEquals(Enum.class, LambdaUtil.getRealClass(lambda));
}, () -> { }, () -> {
// 调用父类方法只能获取到父类类型 // 调用父类方法只能获取到父类类型
//noinspection ResultOfMethodCallIgnored //noinspection ResultOfMethodCallIgnored
final VoidFunc0 lambda = myTeacher::getId; final SerSupplier<?> lambda = myTeacher::getId;
Assert.assertEquals(Entity.class, LambdaUtil.getRealClass(lambda)); Assert.assertEquals(Entity.class, LambdaUtil.getRealClass(lambda));
}, () -> { }, () -> {
// 引用静态带参方法能够获取到正确的参数类型 // 引用静态带参方法能够获取到正确的参数类型
final Func1<MyTeacher, String> lambda = MyTeacher::takeAgeBy; final SerFunction<MyTeacher, String> lambda = MyTeacher::takeAgeBy;
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda)); Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
}, () -> { }, () -> {
// 引用父类静态带参方法只能获取到父类类型 // 引用父类静态带参方法只能获取到父类类型
final Func0<?> lambda = MyTeacher::takeId; final SerSupplier<?> lambda = MyTeacher::takeId;
Assert.assertEquals(Entity.class, LambdaUtil.getRealClass(lambda)); Assert.assertEquals(Entity.class, LambdaUtil.getRealClass(lambda));
}, () -> { }, () -> {
// 引用静态无参方法能够获取到正确的类型 // 引用静态无参方法能够获取到正确的类型
final Func0<String> lambda = MyTeacher::takeAge; final SerSupplier<String> lambda = MyTeacher::takeAge;
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda)); Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
}, () -> { }, () -> {
// 引用父类静态无参方法能够获取到正确的参数类型 // 引用父类静态无参方法能够获取到正确的参数类型
final Func1<MyTeacher, ?> lambda = MyTeacher::takeIdBy; final SerFunction<MyTeacher, ?> lambda = MyTeacher::takeIdBy;
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda)); Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
}, () -> { }, () -> {
// 数组测试 // 数组测试
final VoidFunc1<String[]> lambda = (String[] stringList) -> {}; final SerConsumer<String[]> lambda = (String[] stringList) -> {};
Assert.assertEquals(String[].class, LambdaUtil.getRealClass(lambda)); Assert.assertEquals(String[].class, LambdaUtil.getRealClass(lambda));
}).forEach(Runnable::run); }).forEach(Runnable::run);
} }

View File

@ -5,7 +5,7 @@ import org.junit.Test;
import java.util.HashMap; import java.util.HashMap;
public class FuncMapTest { public class SerFunctionMapTest {
@Test @Test
public void putGetTest(){ public void putGetTest(){

View File

@ -1,7 +1,7 @@
package cn.hutool.db; package cn.hutool.db;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.func.Func1; import cn.hutool.core.lang.func.SerFunction;
import cn.hutool.db.dialect.Dialect; import cn.hutool.db.dialect.Dialect;
import cn.hutool.db.handler.BeanListHandler; import cn.hutool.db.handler.BeanListHandler;
import cn.hutool.db.handler.EntityHandler; import cn.hutool.db.handler.EntityHandler;
@ -191,7 +191,7 @@ public abstract class AbstractDb<R extends AbstractDb<R>> extends DefaultConnect
* @throws DbRuntimeException SQL执行异常 * @throws DbRuntimeException SQL执行异常
* @since 5.7.17 * @since 5.7.17
*/ */
public <T> T query(final Func1<Connection, PreparedStatement> statementFunc, final RsHandler<T> rsh) throws DbRuntimeException { public <T> T query(final SerFunction<Connection, PreparedStatement> statementFunc, final RsHandler<T> rsh) throws DbRuntimeException {
Connection conn = null; Connection conn = null;
try { try {
conn = this.getConnection(); conn = this.getConnection();

View File

@ -1,6 +1,6 @@
package cn.hutool.db; package cn.hutool.db;
import cn.hutool.core.lang.func.Func0; import cn.hutool.core.lang.func.SerSupplier;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import java.util.Collection; import java.util.Collection;
@ -144,7 +144,7 @@ public class ActiveEntity extends Entity {
* @return this * @return this
*/ */
@Override @Override
public ActiveEntity setFields(final Func0<?>... fields) { public ActiveEntity setFields(final SerSupplier<?>... fields) {
return (ActiveEntity) super.setFields(fields); return (ActiveEntity) super.setFields(fields);
} }

View File

@ -1,6 +1,6 @@
package cn.hutool.db; package cn.hutool.db;
import cn.hutool.core.lang.func.VoidFunc1; import cn.hutool.core.lang.func.SerConsumer;
import cn.hutool.db.dialect.Dialect; import cn.hutool.db.dialect.Dialect;
import cn.hutool.db.dialect.DialectFactory; import cn.hutool.db.dialect.DialectFactory;
import cn.hutool.db.ds.DSFactory; import cn.hutool.db.ds.DSFactory;
@ -114,7 +114,7 @@ public class Db extends AbstractDb<Db> {
* @return this * @return this
* @throws SQLException SQL异常 * @throws SQLException SQL异常
*/ */
public Db tx(final VoidFunc1<Db> func) throws SQLException { public Db tx(final SerConsumer<Db> func) throws SQLException {
return tx(null, func); return tx(null, func);
} }
@ -127,7 +127,7 @@ public class Db extends AbstractDb<Db> {
* @return this * @return this
* @throws SQLException SQL异常 * @throws SQLException SQL异常
*/ */
public Db tx(final TransactionLevel transactionLevel, final VoidFunc1<Db> func) throws SQLException { public Db tx(final TransactionLevel transactionLevel, final SerConsumer<Db> func) throws SQLException {
final Connection conn = getConnection(); final Connection conn = getConnection();
// 检查是否支持事务 // 检查是否支持事务

View File

@ -2,7 +2,7 @@ package cn.hutool.db;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.SetUtil; import cn.hutool.core.collection.SetUtil;
import cn.hutool.core.lang.func.Func0; import cn.hutool.core.lang.func.SerSupplier;
import cn.hutool.core.map.Dict; import cn.hutool.core.map.Dict;
import cn.hutool.core.reflect.MethodUtil; import cn.hutool.core.reflect.MethodUtil;
import cn.hutool.core.text.StrUtil; import cn.hutool.core.text.StrUtil;
@ -180,7 +180,7 @@ public class Entity extends Dict {
* @return this * @return this
*/ */
@Override @Override
public Entity setFields(final Func0<?>... fields) { public Entity setFields(final SerSupplier<?>... fields) {
return (Entity) super.setFields(fields); return (Entity) super.setFields(fields);
} }

View File

@ -1,6 +1,6 @@
package cn.hutool.db; package cn.hutool.db;
import cn.hutool.core.lang.func.VoidFunc1; import cn.hutool.core.lang.func.SerConsumer;
import cn.hutool.core.text.StrUtil; import cn.hutool.core.text.StrUtil;
import cn.hutool.db.dialect.Dialect; import cn.hutool.db.dialect.Dialect;
import cn.hutool.db.dialect.DialectFactory; import cn.hutool.db.dialect.DialectFactory;
@ -249,16 +249,16 @@ public class Session extends AbstractDb<Session> implements Closeable {
} }
/** /**
* 在事务中执行操作通过实现{@link VoidFunc1}接口的call方法执行多条SQL语句从而完成事务 * 在事务中执行操作通过实现{@link SerConsumer}接口的call方法执行多条SQL语句从而完成事务
* *
* @param func 函数抽象在函数中执行多个SQL操作多个操作会被合并为同一事务 * @param func 函数抽象在函数中执行多个SQL操作多个操作会被合并为同一事务
* @throws DbRuntimeException SQL异常 * @throws DbRuntimeException SQL异常
* @since 3.2.3 * @since 3.2.3
*/ */
public void tx(final VoidFunc1<Session> func) throws DbRuntimeException { public void tx(final SerConsumer<Session> func) throws DbRuntimeException {
try { try {
beginTransaction(); beginTransaction();
func.call(this); func.accept(this);
commit(); commit();
} catch (final Throwable e) { } catch (final Throwable e) {
quietRollback(); quietRollback();

View File

@ -1,7 +1,7 @@
package cn.hutool.db.sql; package cn.hutool.db.sql;
import cn.hutool.core.collection.iter.ArrayIter; import cn.hutool.core.collection.iter.ArrayIter;
import cn.hutool.core.lang.func.Func1; import cn.hutool.core.lang.func.SerFunction;
import cn.hutool.db.DbRuntimeException; import cn.hutool.db.DbRuntimeException;
import cn.hutool.db.DbUtil; import cn.hutool.db.DbUtil;
import cn.hutool.db.StatementUtil; import cn.hutool.db.StatementUtil;
@ -289,10 +289,10 @@ public class SqlExecutor {
* @throws DbRuntimeException SQL执行异常 * @throws DbRuntimeException SQL执行异常
* @since 5.7.17 * @since 5.7.17
*/ */
public static <T> T query(final Connection conn, final Func1<Connection, PreparedStatement> statementFunc, final RsHandler<T> rsh) throws DbRuntimeException { public static <T> T query(final Connection conn, final SerFunction<Connection, PreparedStatement> statementFunc, final RsHandler<T> rsh) throws DbRuntimeException {
PreparedStatement ps = null; PreparedStatement ps = null;
try { try {
ps = statementFunc.callWithRuntimeException(conn); ps = statementFunc.apply(conn);
return executeQuery(ps, rsh); return executeQuery(ps, rsh);
} finally { } finally {
DbUtil.close(ps); DbUtil.close(ps);