Merge remote-tracking branch 'origin/v6-dev' into v6-dev

# Conflicts:
#	hutool-core/src/main/java/cn/hutool/core/stream/TerminableWrappedStream.java
#	hutool-core/src/main/java/cn/hutool/core/stream/TransformableWrappedStream.java
This commit is contained in:
VampireAchao 2022-09-09 14:40:39 +08:00
commit 814b55cc87
36 changed files with 519 additions and 308 deletions

View File

@ -98,20 +98,22 @@ public class CompositeConverter extends RegisterConverter {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T convert(Type type, final Object value, final T defaultValue, final boolean isCustomFirst) throws ConvertException { public <T> T convert(Type type, final Object value, final T defaultValue, final boolean isCustomFirst) throws ConvertException {
if (TypeUtil.isUnknown(type) && null == defaultValue) {
// 对于用户不指定目标类型的情况返回原值
return (T) value;
}
if (ObjUtil.isNull(value)) { if (ObjUtil.isNull(value)) {
return defaultValue; return defaultValue;
} }
if (TypeUtil.isUnknown(type)) { if (TypeUtil.isUnknown(type)) {
// 对于用户不指定目标类型的情况返回原值
if(null == defaultValue){ if(null == defaultValue){
throw new ConvertException("Unsupported convert to unKnow type: {}", type); return (T) value;
} }
type = defaultValue.getClass(); type = defaultValue.getClass();
} }
// value本身实现了Converter接口直接调用
if(value instanceof Converter){
return ((Converter) value).convert(type, value, defaultValue);
}
if (type instanceof TypeReference) { if (type instanceof TypeReference) {
type = ((TypeReference<?>) type).getType(); type = ((TypeReference<?>) type).getType();
} }

View File

@ -29,9 +29,6 @@ import cn.hutool.core.convert.impl.XMLGregorianCalendarConverter;
import cn.hutool.core.convert.impl.ZoneIdConverter; import cn.hutool.core.convert.impl.ZoneIdConverter;
import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.Opt; import cn.hutool.core.lang.Opt;
import cn.hutool.core.reflect.ClassUtil;
import cn.hutool.core.reflect.TypeUtil;
import cn.hutool.core.util.ServiceLoaderUtil;
import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.datatype.XMLGregorianCalendar;
import java.io.Serializable; import java.io.Serializable;
@ -78,6 +75,25 @@ import java.util.concurrent.atomic.AtomicReference;
public class RegisterConverter implements Converter, Serializable { public class RegisterConverter implements Converter, Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/**
* 类级的内部类也就是静态的成员式内部类该内部类的实例与外部类的实例 没有绑定关系而且只有被调用到才会装载从而实现了延迟加载
*/
private static class SingletonHolder {
/**
* 静态初始化器由JVM来保证线程安全
*/
private static final CompositeConverter INSTANCE = new CompositeConverter();
}
/**
* 获得单例的 ConverterRegistry
*
* @return ConverterRegistry
*/
public static CompositeConverter getInstance() {
return RegisterConverter.SingletonHolder.INSTANCE;
}
/** /**
* 默认类型转换器 * 默认类型转换器
*/ */
@ -92,7 +108,6 @@ public class RegisterConverter implements Converter, Serializable {
*/ */
public RegisterConverter() { public RegisterConverter() {
registerDefault(); registerDefault();
registerCustomBySpi();
} }
@Override @Override
@ -233,20 +248,4 @@ public class RegisterConverter implements Converter, Serializable {
defaultConverterMap.put(Optional.class, new OptionalConverter());// since 5.0.0 defaultConverterMap.put(Optional.class, new OptionalConverter());// since 5.0.0
defaultConverterMap.put(Opt.class, new OptConverter());// since 5.7.16 defaultConverterMap.put(Opt.class, new OptConverter());// since 5.7.16
} }
/**
* 使用SPI加载转换器
*/
private void registerCustomBySpi() {
ServiceLoaderUtil.load(Converter.class).forEach(converter -> {
try {
final Type type = TypeUtil.getTypeArgument(ClassUtil.getClass(converter));
if (null != type) {
putCustom(type, converter);
}
} catch (final Exception ignore) {
// 忽略注册失败的
}
});
}
} }

View File

@ -57,6 +57,11 @@ public class BeanConverter implements Converter, Serializable {
return null; return null;
} }
// value本身实现了Converter接口直接调用
if(value instanceof Converter){
return ((Converter) value).convert(targetType, value);
}
Class<?> targetClass = TypeUtil.getClass(targetType); Class<?> targetClass = TypeUtil.getClass(targetType);
Assert.notNull(targetClass, "Target type is not a class!"); Assert.notNull(targetClass, "Target type is not a class!");
@ -79,6 +84,6 @@ public class BeanConverter implements Converter, Serializable {
return SerializeUtil.deserialize((byte[]) value); return SerializeUtil.deserialize((byte[]) value);
} }
throw new ConvertException("Unsupported source type: {}", value.getClass()); throw new ConvertException("Unsupported source type: [{}] to [{}]", value.getClass(), targetType);
} }
} }

View File

@ -67,7 +67,7 @@ public class DateConverter extends AbstractConverter {
return wrap(targetClass, DateUtil.date((TemporalAccessor) value)); return wrap(targetClass, DateUtil.date((TemporalAccessor) value));
} else if (value instanceof Calendar) { } else if (value instanceof Calendar) {
return wrap(targetClass, DateUtil.date((Calendar) value)); return wrap(targetClass, DateUtil.date((Calendar) value));
} else if (value instanceof Number) { } else if (null == this.format && value instanceof Number) {
return wrap(targetClass, ((Number) value).longValue()); return wrap(targetClass, ((Number) value).longValue());
} else { } else {
// 统一按照字符串处理 // 统一按照字符串处理

View File

@ -67,7 +67,7 @@ public class MapConverter implements Converter, Serializable {
// 二次转换转换键值类型 // 二次转换转换键值类型
map = convert(targetType, keyType, valueType, map); map = convert(targetType, keyType, valueType, map);
} else { } else {
throw new UnsupportedOperationException(StrUtil.format("Unsupport toMap value type: {}", value.getClass().getName())); throw new UnsupportedOperationException(StrUtil.format("Unsupported toMap value type: {}", value.getClass().getName()));
} }
return map; return map;
} }

View File

@ -23,7 +23,7 @@ public interface SerBiConsumer<T, U> extends BiConsumer<T, U>, Serializable {
* @return lambda * @return lambda
*/ */
@SafeVarargs @SafeVarargs
static <T, U> SerBiConsumer<T, U> multi(SerBiConsumer<T, U>... consumers) { static <T, U> SerBiConsumer<T, U> multi(final SerBiConsumer<T, U>... consumers) {
return Stream.of(consumers).reduce(SerBiConsumer::andThen).orElseGet(() -> (o, q) -> {}); return Stream.of(consumers).reduce(SerBiConsumer::andThen).orElseGet(() -> (o, q) -> {});
} }
@ -32,9 +32,8 @@ public interface SerBiConsumer<T, U> extends BiConsumer<T, U>, Serializable {
* *
* @param t the first input argument * @param t the first input argument
* @param u the second input argument * @param u the second input argument
* @throws Exception wrappered checked exceptions for easy using * @throws Exception wrapped checked exceptions for easy using
*/ */
@SuppressWarnings("all")
void accepting(T t, U u) throws Exception; void accepting(T t, U u) throws Exception;
/** /**
@ -44,10 +43,10 @@ public interface SerBiConsumer<T, U> extends BiConsumer<T, U>, Serializable {
* @param u the second input argument * @param u the second input argument
*/ */
@Override @Override
default void accept(T t, U u) { default void accept(final T t, final U u) {
try { try {
accepting(t, u); accepting(t, u);
} catch (Exception e) { } catch (final Exception e) {
throw new UtilException(e); throw new UtilException(e);
} }
} }
@ -64,7 +63,7 @@ public interface SerBiConsumer<T, U> extends BiConsumer<T, U>, Serializable {
* operation followed by the {@code after} operation * operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null * @throws NullPointerException if {@code after} is null
*/ */
default SerBiConsumer<T, U> andThen(SerBiConsumer<? super T, ? super U> after) { default SerBiConsumer<T, U> andThen(final SerBiConsumer<? super T, ? super U> after) {
Objects.requireNonNull(after); Objects.requireNonNull(after);
return (l, r) -> { return (l, r) -> {
accepting(l, r); accepting(l, r);

View File

@ -21,9 +21,8 @@ public interface SerBiFunction<T, U, R> extends BiFunction<T, U, R>, Serializabl
* @param t the first function argument * @param t the first function argument
* @param u the second function argument * @param u the second function argument
* @return the function result * @return the function result
* @throws Exception wrappered checked exceptions * @throws Exception wrapped checked exceptions
*/ */
@SuppressWarnings("all")
R applying(T t, U u) throws Exception; R applying(T t, U u) throws Exception;
/** /**
@ -34,10 +33,10 @@ public interface SerBiFunction<T, U, R> extends BiFunction<T, U, R>, Serializabl
* @return the function result * @return the function result
*/ */
@Override @Override
default R apply(T t, U u) { default R apply(final T t, final U u) {
try { try {
return this.applying(t, u); return this.applying(t, u);
} catch (Exception e) { } catch (final Exception e) {
throw new UtilException(e); throw new UtilException(e);
} }
} }
@ -55,7 +54,7 @@ public interface SerBiFunction<T, U, R> extends BiFunction<T, U, R>, Serializabl
* applies the {@code after} function * applies the {@code after} function
* @throws NullPointerException if after is null * @throws NullPointerException if after is null
*/ */
default <V> SerBiFunction<T, U, V> andThen(SerFunction<? super R, ? extends V> after) { default <V> SerBiFunction<T, U, V> andThen(final SerFunction<? super R, ? extends V> after) {
Objects.requireNonNull(after); Objects.requireNonNull(after);
return (T t, U u) -> after.apply(this.apply(t, u)); return (T t, U u) -> after.apply(this.apply(t, u));
} }

View File

@ -23,9 +23,8 @@ public interface SerBiPredicate<T, U> extends BiPredicate<T, U>, Serializable {
* @param u the second input argument * @param u the second input argument
* @return {@code true} if the input arguments match the predicate, * @return {@code true} if the input arguments match the predicate,
* otherwise {@code false} * otherwise {@code false}
* @throws Exception wrappered checked exceptions * @throws Exception wrapped checked exceptions
*/ */
@SuppressWarnings("all")
boolean testing(T t, U u) throws Exception; boolean testing(T t, U u) throws Exception;
/** /**
@ -37,10 +36,10 @@ public interface SerBiPredicate<T, U> extends BiPredicate<T, U>, Serializable {
* otherwise {@code false} * otherwise {@code false}
*/ */
@Override @Override
default boolean test(T t, U u) { default boolean test(final T t, final U u) {
try { try {
return testing(t, u); return testing(t, u);
} catch (Exception e) { } catch (final Exception e) {
throw new UtilException(e); throw new UtilException(e);
} }
} }
@ -62,7 +61,7 @@ public interface SerBiPredicate<T, U> extends BiPredicate<T, U>, Serializable {
* AND of this predicate and the {@code other} predicate * AND of this predicate and the {@code other} predicate
* @throws NullPointerException if other is null * @throws NullPointerException if other is null
*/ */
default SerBiPredicate<T, U> and(SerBiPredicate<? super T, ? super U> other) { default SerBiPredicate<T, U> and(final SerBiPredicate<? super T, ? super U> other) {
Objects.requireNonNull(other); Objects.requireNonNull(other);
return (T t, U u) -> test(t, u) && other.test(t, u); return (T t, U u) -> test(t, u) && other.test(t, u);
} }
@ -95,7 +94,7 @@ public interface SerBiPredicate<T, U> extends BiPredicate<T, U>, Serializable {
* OR of this predicate and the {@code other} predicate * OR of this predicate and the {@code other} predicate
* @throws NullPointerException if other is null * @throws NullPointerException if other is null
*/ */
default SerBiPredicate<T, U> or(SerBiPredicate<? super T, ? super U> other) { default SerBiPredicate<T, U> or(final SerBiPredicate<? super T, ? super U> other) {
Objects.requireNonNull(other); Objects.requireNonNull(other);
return (T t, U u) -> test(t, u) || other.test(t, u); return (T t, U u) -> test(t, u) || other.test(t, u);
} }

View File

@ -22,9 +22,8 @@ public interface SerBinaryOperator<T> extends BinaryOperator<T>, Serializable {
* @param t the first function argument * @param t the first function argument
* @param u the second function argument * @param u the second function argument
* @return the function result * @return the function result
* @throws Exception wrappered checked exceptions * @throws Exception wrapped checked exceptions
*/ */
@SuppressWarnings("all")
T applying(T t, T u) throws Exception; T applying(T t, T u) throws Exception;
/** /**
@ -35,10 +34,10 @@ public interface SerBinaryOperator<T> extends BinaryOperator<T>, Serializable {
* @return the function result * @return the function result
*/ */
@Override @Override
default T apply(T t, T u) { default T apply(final T t, final T u) {
try { try {
return this.applying(t, u); return this.applying(t, u);
} catch (Exception e) { } catch (final Exception e) {
throw new UtilException(e); throw new UtilException(e);
} }
} }
@ -53,7 +52,7 @@ public interface SerBinaryOperator<T> extends BinaryOperator<T>, Serializable {
* according to the supplied {@code Comparator} * according to the supplied {@code Comparator}
* @throws NullPointerException if the argument is null * @throws NullPointerException if the argument is null
*/ */
static <T> SerBinaryOperator<T> minBy(Comparator<? super T> comparator) { static <T> SerBinaryOperator<T> minBy(final Comparator<? super T> comparator) {
Objects.requireNonNull(comparator); Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) <= 0 ? a : b; return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
} }
@ -68,7 +67,7 @@ public interface SerBinaryOperator<T> extends BinaryOperator<T>, Serializable {
* according to the supplied {@code Comparator} * according to the supplied {@code Comparator}
* @throws NullPointerException if the argument is null * @throws NullPointerException if the argument is null
*/ */
static <T> SerBinaryOperator<T> maxBy(Comparator<? super T> comparator) { static <T> SerBinaryOperator<T> maxBy(final Comparator<? super T> comparator) {
Objects.requireNonNull(comparator); Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) >= 0 ? a : b; return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
} }

View File

@ -20,9 +20,8 @@ public interface SerConsumer<T> extends Consumer<T>, Serializable {
* Performs this operation on the given argument. * Performs this operation on the given argument.
* *
* @param t the input argument * @param t the input argument
* @throws Exception wrappered checked exceptions * @throws Exception wrapped checked exceptions
*/ */
@SuppressWarnings("all")
void accepting(T t) throws Exception; void accepting(T t) throws Exception;
/** /**
@ -31,10 +30,10 @@ public interface SerConsumer<T> extends Consumer<T>, Serializable {
* @param t the input argument * @param t the input argument
*/ */
@Override @Override
default void accept(T t) { default void accept(final T t) {
try { try {
accepting(t); accepting(t);
} catch (Exception e) { } catch (final Exception e) {
throw new UtilException(e); throw new UtilException(e);
} }
} }
@ -47,7 +46,7 @@ public interface SerConsumer<T> extends Consumer<T>, Serializable {
* @return lambda * @return lambda
*/ */
@SafeVarargs @SafeVarargs
static <T> SerConsumer<T> multi(SerConsumer<T>... consumers) { static <T> SerConsumer<T> multi(final SerConsumer<T>... consumers) {
return Stream.of(consumers).reduce(SerConsumer::andThen).orElseGet(() -> o -> {}); return Stream.of(consumers).reduce(SerConsumer::andThen).orElseGet(() -> o -> {});
} }
@ -63,7 +62,7 @@ public interface SerConsumer<T> extends Consumer<T>, Serializable {
* operation followed by the {@code after} operation * operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null * @throws NullPointerException if {@code after} is null
*/ */
default SerConsumer<T> andThen(SerConsumer<? super T> after) { default SerConsumer<T> andThen(final SerConsumer<? super T> after) {
Objects.requireNonNull(after); Objects.requireNonNull(after);
return (T t) -> { return (T t) -> {
accept(t); accept(t);

View File

@ -23,9 +23,8 @@ public interface SerConsumer3<P1, P2, P3> extends Serializable {
* @param p1 参数一 * @param p1 参数一
* @param p2 参数二 * @param p2 参数二
* @param p3 参数三 * @param p3 参数三
* @throws Exception wrappered checked exceptions * @throws Exception wrapped checked exceptions
*/ */
@SuppressWarnings("all")
void accepting(P1 p1, P2 p2, P3 p3) throws Exception; void accepting(P1 p1, P2 p2, P3 p3) throws Exception;
/** /**

View File

@ -19,9 +19,8 @@ public interface SerFunction<T, R> extends Function<T, R>, Serializable {
* *
* @param t the function argument * @param t the function argument
* @return the function result * @return the function result
* @throws Exception wrappered checked exceptions * @throws Exception wrapped checked exceptions
*/ */
@SuppressWarnings("all")
R applying(T t) throws Exception; R applying(T t) throws Exception;
/** /**

View File

@ -22,7 +22,7 @@ public interface SerPredicate<T> extends Predicate<T>, Serializable {
* @param t the input argument * @param t the input argument
* @return {@code true} if the input argument matches the predicate, * @return {@code true} if the input argument matches the predicate,
* otherwise {@code false} * otherwise {@code false}
* @throws Exception wrappered checked exceptions * @throws Exception wrapped checked exceptions
*/ */
boolean testing(T t) throws Exception; boolean testing(T t) throws Exception;
@ -34,10 +34,10 @@ public interface SerPredicate<T> extends Predicate<T>, Serializable {
* otherwise {@code false} * otherwise {@code false}
*/ */
@Override @Override
default boolean test(T t) { default boolean test(final T t) {
try { try {
return testing(t); return testing(t);
} catch (Exception e) { } catch (final Exception e) {
throw new UtilException(e); throw new UtilException(e);
} }
} }
@ -50,7 +50,7 @@ public interface SerPredicate<T> extends Predicate<T>, Serializable {
* @return lambda * @return lambda
*/ */
@SafeVarargs @SafeVarargs
static <T> SerPredicate<T> multiAnd(SerPredicate<T>... predicates) { static <T> SerPredicate<T> multiAnd(final SerPredicate<T>... predicates) {
return Stream.of(predicates).reduce(SerPredicate::and).orElseGet(() -> o -> true); return Stream.of(predicates).reduce(SerPredicate::and).orElseGet(() -> o -> true);
} }
@ -62,7 +62,7 @@ public interface SerPredicate<T> extends Predicate<T>, Serializable {
* @return lambda * @return lambda
*/ */
@SafeVarargs @SafeVarargs
static <T> SerPredicate<T> multiOr(SerPredicate<T>... predicates) { static <T> SerPredicate<T> multiOr(final SerPredicate<T>... predicates) {
return Stream.of(predicates).reduce(SerPredicate::or).orElseGet(() -> o -> false); return Stream.of(predicates).reduce(SerPredicate::or).orElseGet(() -> o -> false);
} }
@ -76,7 +76,7 @@ public interface SerPredicate<T> extends Predicate<T>, Serializable {
* @return a predicate that tests if two arguments are equal according * @return a predicate that tests if two arguments are equal according
* to {@link Objects#equals(Object, Object)} * to {@link Objects#equals(Object, Object)}
*/ */
static <T> SerPredicate<T> isEqual(Object... targetRef) { static <T> SerPredicate<T> isEqual(final Object... targetRef) {
return (null == targetRef) return (null == targetRef)
? Objects::isNull ? Objects::isNull
: object -> Stream.of(targetRef).allMatch(target -> target.equals(object)); : object -> Stream.of(targetRef).allMatch(target -> target.equals(object));
@ -98,7 +98,7 @@ public interface SerPredicate<T> extends Predicate<T>, Serializable {
* AND of this predicate and the {@code other} predicate * AND of this predicate and the {@code other} predicate
* @throws NullPointerException if other is null * @throws NullPointerException if other is null
*/ */
default SerPredicate<T> and(SerPredicate<? super T> other) { default SerPredicate<T> and(final SerPredicate<? super T> other) {
Objects.requireNonNull(other); Objects.requireNonNull(other);
return t -> test(t) && other.test(t); return t -> test(t) && other.test(t);
} }
@ -131,7 +131,7 @@ public interface SerPredicate<T> extends Predicate<T>, Serializable {
* OR of this predicate and the {@code other} predicate * OR of this predicate and the {@code other} predicate
* @throws NullPointerException if other is null * @throws NullPointerException if other is null
*/ */
default SerPredicate<T> or(SerPredicate<? super T> other) { default SerPredicate<T> or(final SerPredicate<? super T> other) {
Objects.requireNonNull(other); Objects.requireNonNull(other);
return t -> test(t) || other.test(t); return t -> test(t) || other.test(t);
} }

View File

@ -24,10 +24,9 @@ public interface SerRunnable extends Runnable, Serializable {
* The general contract of the method <code>run</code> is that it may * The general contract of the method <code>run</code> is that it may
* take any action whatsoever. * take any action whatsoever.
* *
* @throws Exception wrappered checked exceptions * @throws Exception wrapped checked exceptions
* @see Thread#run() * @see Thread#run()
*/ */
@SuppressWarnings("all")
void running() throws Exception; void running() throws Exception;
/** /**
@ -45,7 +44,7 @@ public interface SerRunnable extends Runnable, Serializable {
default void run() { default void run() {
try { try {
running(); running();
} catch (Exception e) { } catch (final Exception e) {
throw new UtilException(e); throw new UtilException(e);
} }
} }
@ -56,7 +55,7 @@ public interface SerRunnable extends Runnable, Serializable {
* @param serRunnableArray lambda * @param serRunnableArray lambda
* @return lambda * @return lambda
*/ */
static SerRunnable multi(SerRunnable... serRunnableArray) { static SerRunnable multi(final SerRunnable... serRunnableArray) {
return () -> Stream.of(serRunnableArray).forEach(SerRunnable::run); return () -> Stream.of(serRunnableArray).forEach(SerRunnable::run);
} }

View File

@ -19,9 +19,8 @@ public interface SerSupplier<T> extends Supplier<T>, Serializable {
* Gets a result. * Gets a result.
* *
* @return a result * @return a result
* @throws Exception wrappered checked exceptions * @throws Exception wrapped checked exceptions
*/ */
@SuppressWarnings("all")
T getting() throws Exception; T getting() throws Exception;
/** /**
@ -33,7 +32,7 @@ public interface SerSupplier<T> extends Supplier<T>, Serializable {
default T get() { default T get() {
try { try {
return getting(); return getting();
} catch (Exception e) { } catch (final Exception e) {
throw new UtilException(e); throw new UtilException(e);
} }
} }
@ -46,7 +45,7 @@ public interface SerSupplier<T> extends Supplier<T>, Serializable {
* @return lambda * @return lambda
*/ */
@SafeVarargs @SafeVarargs
static <T> SerSupplier<T> last(SerSupplier<T>... serSups) { static <T> SerSupplier<T> last(final SerSupplier<T>... serSups) {
return Stream.of(serSups).reduce((l, r) -> r).orElseGet(() -> () -> null); return Stream.of(serSups).reduce((l, r) -> r).orElseGet(() -> () -> null);
} }

View File

@ -20,9 +20,8 @@ public interface SerUnaryOperator<T> extends UnaryOperator<T>, Serializable {
* *
* @param t the function argument * @param t the function argument
* @return the function result * @return the function result
* @throws Exception wrappered checked exceptions * @throws Exception wrapped checked exceptions
*/ */
@SuppressWarnings("all")
T applying(T t) throws Exception; T applying(T t) throws Exception;
/** /**
@ -32,10 +31,10 @@ public interface SerUnaryOperator<T> extends UnaryOperator<T>, Serializable {
* @return the function result * @return the function result
*/ */
@Override @Override
default T apply(T t) { default T apply(final T t) {
try { try {
return applying(t); return applying(t);
} catch (Exception e) { } catch (final Exception e) {
throw new UtilException(e); throw new UtilException(e);
} }
} }
@ -61,7 +60,7 @@ public interface SerUnaryOperator<T> extends UnaryOperator<T>, Serializable {
* @return identity after casting * @return identity after casting
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
static <T, R, F extends Function<T, R>> SerUnaryOperator<T> casting(F function) { static <T, R, F extends Function<T, R>> SerUnaryOperator<T> casting(final F function) {
return t -> (T) function.apply(t); return t -> (T) function.apply(t);
} }

View File

@ -7,10 +7,11 @@ 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.SerSupplier;
import cn.hutool.core.lang.func.LambdaUtil; import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.lang.func.SerSupplier;
import cn.hutool.core.lang.getter.BasicTypeGetter; import cn.hutool.core.lang.getter.BasicTypeGetter;
import java.lang.reflect.Type;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.sql.Time; import java.sql.Time;
@ -564,7 +565,7 @@ public class Dict extends CustomKeyMap<String, Object> implements BasicTypeGette
* @see BeanPath#get(Object) * @see BeanPath#get(Object)
* @since 5.7.14 * @since 5.7.14
*/ */
public <T> T getByPath(final String expression, final Class<T> resultType) { public <T> T getByPath(final String expression, final Type resultType) {
return Convert.convert(resultType, getByPath(expression)); return Convert.convert(resultType, getByPath(expression));
} }
// -------------------------------------------------------------------- Get end // -------------------------------------------------------------------- Get end
@ -573,7 +574,7 @@ public class Dict extends CustomKeyMap<String, Object> implements BasicTypeGette
public Dict clone() { public Dict clone() {
try { try {
return (Dict) super.clone(); return (Dict) super.clone();
} catch (CloneNotSupportedException e) { } catch (final CloneNotSupportedException e) {
throw new CloneRuntimeException(e); throw new CloneRuntimeException(e);
} }
} }

View File

@ -342,7 +342,7 @@ public class EasyStream<T> extends AbstractEnhancedWrappedStream<T, EasyStream<T
Objects.requireNonNull(pIdValuesMap); Objects.requireNonNull(pIdValuesMap);
final MutableObj<Consumer<List<T>>> recursiveRef = new MutableObj<>(); final MutableObj<Consumer<List<T>>> recursiveRef = new MutableObj<>();
final Consumer<List<T>> recursive = values -> EasyStream.of(values, isParallel()).forEach(value -> { final Consumer<List<T>> recursive = values -> EasyStream.of(values, isParallel()).forEach(value -> {
List<T> children = pIdValuesMap.get(idGetter.apply(value)); final List<T> children = pIdValuesMap.get(idGetter.apply(value));
childrenSetter.accept(value, children); childrenSetter.accept(value, children);
recursiveRef.get().accept(children); recursiveRef.get().accept(children);
}); });

View File

@ -17,52 +17,52 @@ import java.util.stream.Stream;
* *
* @param <T> 流中的元素类型 * @param <T> 流中的元素类型
* @param <S> {@link TerminableWrappedStream}的实现类类型 * @param <S> {@link TerminableWrappedStream}的实现类类型
* @author huangchengxing VampireAchao * @author huangchengxing
* @since 6.0.0 * @since 6.0.0
*/ */
public interface TerminableWrappedStream<T, S extends TerminableWrappedStream<T, S>> extends WrappedStream<T, S> { public interface TerminableWrappedStream<T, S extends TerminableWrappedStream<T, S>> extends WrappedStream<T, S> {
// region ============ to collection ============ // region ============ to collection ============
/** /**
* 转换为{@link ArrayList} * 转换为{@link ArrayList}
* *
* @return 集合 * @return 集合
* @see #toColl(Supplier)
*/
default List<T> toList() {
return this.toColl(ArrayList::new);
}
/**
* 换为不可变集合
*
* @return 集合
* @see #toColl(Supplier) * @see #toColl(Supplier)
*/ */
default List<T> toList() { default List<T> toUnmodifiableList() {
return this.toColl(ArrayList::new); return Collections.unmodifiableList(this.toList());
} }
/** /**
* 换为不可变集合 * 转换为HashSet
* *
* @return 集合 * @return 集合
* @see #toColl(Supplier) * @see #toColl(Supplier)
*/ */
default List<T> toUnmodifiableList() { default Set<T> toSet() {
return Collections.unmodifiableList(this.toList()); return this.toColl(HashSet::new);
} }
/** /**
* 转换为HashSet * 换为不可变集合
* *
* @return 集合 * @return 集合
* @see #toColl(Supplier) * @see #toColl(Supplier)
*/ */
default Set<T> toSet() { default Set<T> toUnmodifiableSet() {
return this.toColl(HashSet::new); return Collections.unmodifiableSet(this.toSet());
} }
/**
* 换为不可变集合
*
* @return 集合
* @see #toColl(Supplier)
*/
default Set<T> toUnmodifiableSet() {
return Collections.unmodifiableSet(this.toSet());
}
/** /**
* 转换成集合 * 转换成集合
@ -76,145 +76,145 @@ public interface TerminableWrappedStream<T, S extends TerminableWrappedStream<T,
return unwrap().collect(Collectors.toCollection(collectionFactory)); return unwrap().collect(Collectors.toCollection(collectionFactory));
} }
// endregion // endregion
// region ============ to map ============ // region ============ to map ============
/** /**
* 转换为mapkey为给定操作执行后的返回值,value为当前元素 * 转换为mapkey为给定操作执行后的返回值,value为当前元素
* *
* @param keyMapper 指定的key操作 * @param keyMapper 指定的key操作
* @param <K> key类型 * @param <K> key类型
* @return map * @return map
* @see #toMap(Function, Function, BinaryOperator, Supplier) * @see #toMap(Function, Function, BinaryOperator, Supplier)
*/ */
default <K> Map<K, T> toMap(final Function<? super T, ? extends K> keyMapper) { default <K> Map<K, T> toMap(final Function<? super T, ? extends K> keyMapper) {
return this.toMap(keyMapper, Function.identity()); return this.toMap(keyMapper, Function.identity());
} }
/** /**
* 转换为mapkey,value为给定操作执行后的返回值 * 转换为mapkey,value为给定操作执行后的返回值
* *
* @param keyMapper 指定的key操作 * @param keyMapper 指定的key操作
* @param valueMapper 指定value操作 * @param valueMapper 指定value操作
* @param <K> key类型 * @param <K> key类型
* @param <U> value类型 * @param <U> value类型
* @return map * @return map
* @see #toMap(Function, Function, BinaryOperator, Supplier) * @see #toMap(Function, Function, BinaryOperator, Supplier)
*/ */
default <K, U> Map<K, U> toMap( default <K, U> Map<K, U> toMap(
final Function<? super T, ? extends K> keyMapper, final Function<? super T, ? extends U> valueMapper) { final Function<? super T, ? extends K> keyMapper, final Function<? super T, ? extends U> valueMapper) {
return this.toMap(keyMapper, valueMapper, (l, r) -> r); return this.toMap(keyMapper, valueMapper, (l, r) -> r);
} }
/** /**
* 转换为不可变mapkey,value为给定操作执行后的返回值 * 转换为不可变mapkey,value为给定操作执行后的返回值
* *
* @param keyMapper 指定的key操作 * @param keyMapper 指定的key操作
* @param valueMapper 指定value操作 * @param valueMapper 指定value操作
* @param <K> key类型 * @param <K> key类型
* @param <U> value类型 * @param <U> value类型
* @return map * @return map
* @see #toMap(Function, Function, BinaryOperator, Supplier) * @see #toMap(Function, Function, BinaryOperator, Supplier)
*/ */
default <K, U> Map<K, U> toUnmodifiableMap( default <K, U> Map<K, U> toUnmodifiableMap(
final Function<? super T, ? extends K> keyMapper, final Function<? super T, ? extends U> valueMapper) { final Function<? super T, ? extends K> keyMapper, final Function<? super T, ? extends U> valueMapper) {
return Collections.unmodifiableMap(this.toMap(keyMapper, valueMapper)); return Collections.unmodifiableMap(this.toMap(keyMapper, valueMapper));
} }
/** /**
* 转换为mapkey,value为给定操作执行后的返回值 * 转换为mapkey,value为给定操作执行后的返回值
* *
* @param keyMapper 指定的key操作 * @param keyMapper 指定的key操作
* @param valueMapper 指定value操作 * @param valueMapper 指定value操作
* @param mergeFunction 合并操作 * @param mergeFunction 合并操作
* @param <K> key类型 * @param <K> key类型
* @param <U> value类型 * @param <U> value类型
* @return map * @return map
* @see #toMap(Function, Function, BinaryOperator, Supplier) * @see #toMap(Function, Function, BinaryOperator, Supplier)
*/ */
default <K, U> Map<K, U> toMap( default <K, U> Map<K, U> toMap(
final Function<? super T, ? extends K> keyMapper, final Function<? super T, ? extends K> keyMapper,
final Function<? super T, ? extends U> valueMapper, final Function<? super T, ? extends U> valueMapper,
final BinaryOperator<U> mergeFunction) { final BinaryOperator<U> mergeFunction) {
return this.toMap(keyMapper, valueMapper, mergeFunction, HashMap::new); return this.toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
} }
/** /**
* 转换为不可变mapkey,value为给定操作执行后的返回值 * 转换为不可变mapkey,value为给定操作执行后的返回值
* *
* @param keyMapper 指定的key操作 * @param keyMapper 指定的key操作
* @param valueMapper 指定value操作 * @param valueMapper 指定value操作
* @param mergeFunction 合并操作 * @param mergeFunction 合并操作
* @param <K> key类型 * @param <K> key类型
* @param <U> value类型 * @param <U> value类型
* @return map * @return map
* @see #toMap(Function, Function, BinaryOperator, Supplier) * @see #toMap(Function, Function, BinaryOperator, Supplier)
*/ */
default <K, U> Map<K, U> toUnmodifiableMap( default <K, U> Map<K, U> toUnmodifiableMap(
final Function<? super T, ? extends K> keyMapper, final Function<? super T, ? extends K> keyMapper,
final Function<? super T, ? extends U> valueMapper, final Function<? super T, ? extends U> valueMapper,
final BinaryOperator<U> mergeFunction) { final BinaryOperator<U> mergeFunction) {
return Collections.unmodifiableMap( return Collections.unmodifiableMap(
this.toMap(keyMapper, valueMapper, mergeFunction, HashMap::new) this.toMap(keyMapper, valueMapper, mergeFunction, HashMap::new)
); );
} }
/** /**
* 转换为mapkey,value为给定操作执行后的返回值 * 转换为mapkey,value为给定操作执行后的返回值
* *
* @param keyMapper 指定的key操作 * @param keyMapper 指定的key操作
* @param valueMapper 指定value操作 * @param valueMapper 指定value操作
* @param mergeFunction 合并操作 * @param mergeFunction 合并操作
* @param mapSupplier map工厂 * @param mapSupplier map工厂
* @param <K> key类型 * @param <K> key类型
* @param <U> value类型 * @param <U> value类型
* @param <M> map类型 * @param <M> map类型
* @return map * @return map
*/ */
default <K, U, M extends Map<K, U>> M toMap( default <K, U, M extends Map<K, U>> M toMap(
final Function<? super T, ? extends K> keyMapper, final Function<? super T, ? extends K> keyMapper,
final Function<? super T, ? extends U> valueMapper, final Function<? super T, ? extends U> valueMapper,
final BinaryOperator<U> mergeFunction, final BinaryOperator<U> mergeFunction,
Supplier<M> mapSupplier) { final Supplier<M> mapSupplier) {
Objects.requireNonNull(keyMapper); Objects.requireNonNull(keyMapper);
Objects.requireNonNull(valueMapper); Objects.requireNonNull(valueMapper);
Objects.requireNonNull(mergeFunction); Objects.requireNonNull(mergeFunction);
Objects.requireNonNull(mapSupplier); Objects.requireNonNull(mapSupplier);
return unwrap().collect(Collectors.toMap(keyMapper, valueMapper, mergeFunction, mapSupplier)); return unwrap().collect(Collectors.toMap(keyMapper, valueMapper, mergeFunction, mapSupplier));
} }
// endregion // endregion
// region ============ to zip ============ // region ============ to zip ============
/** /**
* 与给定的可迭代对象转换成mapkey为现有元素value为给定可迭代对象迭代的元素<br> * 与给定的可迭代对象转换成mapkey为现有元素value为给定可迭代对象迭代的元素<br>
* 至少包含全部的key如果对应位置上的value不存在则为null * 至少包含全部的key如果对应位置上的value不存在则为null
* *
* @param other 可迭代对象 * @param other 可迭代对象
* @param <R> 可迭代对象迭代的元素类型 * @param <R> 可迭代对象迭代的元素类型
* @return mapkey为现有元素value为给定可迭代对象迭代的元素;<br> * @return mapkey为现有元素value为给定可迭代对象迭代的元素;<br>
* 至少包含全部的key如果对应位置上的value不存在则为null;<br> * 至少包含全部的key如果对应位置上的value不存在则为null;<br>
* 如果key重复, 则保留最后一个关联的value;<br> * 如果key重复, 则保留最后一个关联的value;<br>
*/ */
default <R> Map<T, R> toZip(final Iterable<R> other) { default <R> Map<T, R> toZip(final Iterable<R> other) {
Objects.requireNonNull(other); Objects.requireNonNull(other);
// value对象迭代器 // value对象迭代器
final Iterator<R> iterator = Opt.ofNullable(other).map(Iterable::iterator).orElseGet(Collections::emptyIterator); final Iterator<R> iterator = Opt.ofNullable(other).map(Iterable::iterator).orElseGet(Collections::emptyIterator);
if (this.isParallel()) { if (this.isParallel()) {
final List<T> keyList = toList(); final List<T> keyList = toList();
final Map<T, R> map = new HashMap<>(keyList.size()); final Map<T, R> map = new HashMap<>(keyList.size());
for (T key : keyList) { for (final T key : keyList) {
map.put(key, iterator.hasNext() ? iterator.next() : null); map.put(key, iterator.hasNext() ? iterator.next() : null);
} }
return map; return map;
} else { } else {
return this.toMap(Function.identity(), e -> iterator.hasNext() ? iterator.next() : null); return this.toMap(Function.identity(), e -> iterator.hasNext() ? iterator.next() : null);
} }
} }
// endregion // endregion
// region ============ to optional ============ // region ============ to optional ============
@ -408,7 +408,7 @@ public interface TerminableWrappedStream<T, S extends TerminableWrappedStream<T,
* @see #group(Function, Supplier, Collector) * @see #group(Function, Supplier, Collector)
*/ */
default <K, A, D> Map<K, D> group( default <K, A, D> Map<K, D> group(
final Function<? super T, ? extends K> classifier, final Collector<? super T, A, D> downstream) { final Function<? super T, ? extends K> classifier, final Collector<? super T, A, D> downstream) {
return this.group(classifier, HashMap::new, downstream); return this.group(classifier, HashMap::new, downstream);
} }
@ -426,9 +426,9 @@ public interface TerminableWrappedStream<T, S extends TerminableWrappedStream<T,
* @see CollectorUtil#groupingBy(Function, Supplier, Collector) * @see CollectorUtil#groupingBy(Function, Supplier, Collector)
*/ */
default <K, D, A, M extends Map<K, D>> M group( default <K, D, A, M extends Map<K, D>> M group(
final Function<? super T, ? extends K> classifier, final Function<? super T, ? extends K> classifier,
final Supplier<M> mapFactory, final Supplier<M> mapFactory,
final Collector<? super T, A, D> downstream) { final Collector<? super T, A, D> downstream) {
Objects.requireNonNull(classifier); Objects.requireNonNull(classifier);
Objects.requireNonNull(mapFactory); Objects.requireNonNull(mapFactory);
Objects.requireNonNull(downstream); Objects.requireNonNull(downstream);
@ -449,9 +449,9 @@ public interface TerminableWrappedStream<T, S extends TerminableWrappedStream<T,
/** /**
* 根据给定判断条件分组 * 根据给定判断条件分组
* *
* @param predicate 判断条件 * @param <C> 值类型
* @param predicate 判断条件
* @param collFactory 提供的集合 * @param collFactory 提供的集合
* @param <C> 集合类型
* @return map * @return map
* @see #partition(Predicate, Collector) * @see #partition(Predicate, Collector)
*/ */
@ -464,7 +464,7 @@ public interface TerminableWrappedStream<T, S extends TerminableWrappedStream<T,
* *
* @param predicate 判断条件 * @param predicate 判断条件
* @param downstream 下游操作 * @param downstream 下游操作
* @param <R> 返回值类型 * @param <R> 返回值类型
* @return map * @return map
*/ */
default <R> Map<Boolean, R> partition(final Predicate<T> predicate, final Collector<T, ?, R> downstream) { default <R> Map<Boolean, R> partition(final Predicate<T> predicate, final Collector<T, ?, R> downstream) {

View File

@ -3,6 +3,7 @@ package cn.hutool.core.stream;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.collection.iter.IterUtil; import cn.hutool.core.collection.iter.IterUtil;
import cn.hutool.core.lang.Console; import cn.hutool.core.lang.Console;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.lang.mutable.MutableInt; import cn.hutool.core.lang.mutable.MutableInt;
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;
@ -23,7 +24,7 @@ import java.util.stream.StreamSupport;
* *
* @param <T> 流中的元素类型 * @param <T> 流中的元素类型
* @param <S> {@link TransformableWrappedStream}的实现类类型 * @param <S> {@link TransformableWrappedStream}的实现类类型
* @author huangchengxing VampireAchao * @author huangchengxing
* @since 6.0.0 * @since 6.0.0
*/ */
public interface TransformableWrappedStream<T, S extends TransformableWrappedStream<T, S>> extends WrappedStream<T, S> { public interface TransformableWrappedStream<T, S extends TransformableWrappedStream<T, S>> extends WrappedStream<T, S> {
@ -39,15 +40,24 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
* @return 合并后的结果对象的流 * @return 合并后的结果对象的流
*/ */
default <U, R> EasyStream<R> zip( default <U, R> EasyStream<R> zip(
final Iterable<U> other, final Iterable<U> other,
final BiFunction<? super T, ? super U, ? extends R> zipper) { final BiFunction<? super T, ? super U, ? extends R> zipper) {
Objects.requireNonNull(zipper); Objects.requireNonNull(zipper);
Map<Integer, T> idxIdentityMap = mapIdx((e, idx) -> MapUtil.entry(idx, e)).collect(CollectorUtil.entryToMap()); final Spliterator<T> keys = spliterator();
Map<Integer, U> idxOtherMap = EasyStream.of(other).mapIdx((e, idx) -> MapUtil.entry(idx, e)).collect(CollectorUtil.entryToMap()); final Spliterator<U> values = Opt.ofNullable(other).map(Iterable::spliterator).orElseGet(Spliterators::emptySpliterator);
if (idxIdentityMap.size() <= idxOtherMap.size()) { // 获取两个Spliterator的中较小的数量
return EasyStream.of(idxIdentityMap.keySet(), isParallel()).map(k -> zipper.apply(idxIdentityMap.get(k), idxOtherMap.get(k))); // 如果Spliterator经过流操作, getExactSizeIfKnown()可能会返回-1, 所以默认大小为 ArrayList.DEFAULT_CAPACITY
final int sizeIfKnown = (int) Math.max(Math.min(keys.getExactSizeIfKnown(), values.getExactSizeIfKnown()), 10);
final List<R> list = new ArrayList<>(sizeIfKnown);
// 保存第一个Spliterator的值
final MutableObj<T> key = new MutableObj<>();
// 保存第二个Spliterator的值
final MutableObj<U> value = new MutableObj<>();
// 当两个Spliterator中都还有剩余元素时
while (keys.tryAdvance(key::set) && values.tryAdvance(value::set)) {
list.add(zipper.apply(key.get(), value.get()));
} }
return EasyStream.of(idxOtherMap.keySet(), isParallel()).map(k -> zipper.apply(idxIdentityMap.get(k), idxOtherMap.get(k))); return EasyStream.of(list).parallel(isParallel()).onClose(unwrap()::close);
} }
/** /**
@ -68,9 +78,9 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
return EasyStream.<EasyStream<T>>of(EasyStream.of(list, isParallel())); return EasyStream.<EasyStream<T>>of(EasyStream.of(list, isParallel()));
} }
return EasyStream.iterate(0, i -> i < size, i -> i + batchSize) return EasyStream.iterate(0, i -> i < size, i -> i + batchSize)
.map(skip -> EasyStream.of(list.subList(skip, Math.min(size, skip + batchSize)), isParallel())) .map(skip -> EasyStream.of(list.subList(skip, Math.min(size, skip + batchSize)), isParallel()))
.parallel(isParallel()) .parallel(isParallel())
.onClose(unwrap()::close); .onClose(unwrap()::close);
} }
/** /**
@ -104,8 +114,8 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
/** /**
* 将当前流转为键值对流 * 将当前流转为键值对流
* *
* @param keyMapper 键的映射方法 * @param keyMapper 键的映射方法
* @param <K> 键类型 * @param <K> 键类型
* @return {@link EntryStream}实例 * @return {@link EntryStream}实例
*/ */
default <K> EntryStream<K, T> toEntries(final Function<T, K> keyMapper) { default <K> EntryStream<K, T> toEntries(final Function<T, K> keyMapper) {
@ -145,10 +155,11 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
* @param items 放入值 * @param items 放入值
* @return 操作后的流 * @return 操作后的流
*/ */
@SuppressWarnings("unchecked")
default S splice(final int start, final int deleteCount, final T... items) { default S splice(final int start, final int deleteCount, final T... items) {
final List<T> elements = unwrap().collect(Collectors.toList()); final List<T> elements = unwrap().collect(Collectors.toList());
return wrap(ListUtil.splice(elements, start, deleteCount, items).stream()) return wrap(ListUtil.splice(elements, start, deleteCount, items).stream())
.parallel(isParallel()); .parallel(isParallel());
} }
/** /**
@ -181,15 +192,15 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
} }
/** /**
* 删除流中与断言匹配的元素当遇到第一个不匹配的元素时终止返回由剩余不匹配的元素组成的流 * 删除流中与断言匹配的元素当遇到第一个不匹配的元素时终止返回由剩余不匹配的元素组成的流<br>
* eg: * eg:
* <pre>{@code * <pre>{@code
* EasyStream.of(1, 2, 3, 4, 5) * EasyStream.of(1, 2, 3, 4, 5)
* .dropWhile(i -> !Objects.equals(3, i)) // 删除不为3的元素一直到遇到第一个3为止 * .dropWhile(i -> !Objects.equals(3, i)) // 删除不为3的元素一直到遇到第一个3为止
* .toList(); // = [3, 4, 5] * .toList(); // = [3, 4, 5]
* }</pre> * }</pre>
* <p> *
* {@code JDK9}中的{@code dropWhile}方法不太一样此操作为顺序且有状态的中间操作 * <p>{@code JDK9}中的{@code dropWhile}方法不太一样此操作为顺序且有状态的中间操作
* 即使在并行流中该操作仍然是顺序执行的并且不影响后续的并行操作 * 即使在并行流中该操作仍然是顺序执行的并且不影响后续的并行操作
* <pre>{@code * <pre>{@code
* EasyStream.iterate(1, i -> i + 1) * EasyStream.iterate(1, i -> i + 1)
@ -251,7 +262,6 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
/** /**
* 返回与指定函数将元素作为参数执行后组成的流操作带下标并行流时下标永远为-1 * 返回与指定函数将元素作为参数执行后组成的流操作带下标并行流时下标永远为-1
* 这是一个无状态中间操作 * 这是一个无状态中间操作
*
* @param action 指定的函数 * @param action 指定的函数
* @return 返回叠加操作后的FastStream * @return 返回叠加操作后的FastStream
* @apiNote 该方法存在的意义主要是用来调试 * @apiNote 该方法存在的意义主要是用来调试
@ -270,7 +280,7 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
if (isParallel()) { if (isParallel()) {
return peek(e -> action.accept(e, NOT_FOUND_ELEMENT_INDEX)); return peek(e -> action.accept(e, NOT_FOUND_ELEMENT_INDEX));
} else { } else {
AtomicInteger index = new AtomicInteger(NOT_FOUND_ELEMENT_INDEX); final AtomicInteger index = new AtomicInteger(NOT_FOUND_ELEMENT_INDEX);
return peek(e -> action.accept(e, index.incrementAndGet())); return peek(e -> action.accept(e, index.incrementAndGet()));
} }
} }
@ -309,6 +319,7 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
* @param obj 元素 * @param obj 元素
* @return * @return
*/ */
@SuppressWarnings({"SpellCheckingInspection", "unchecked"})
default S unshift(final T... obj) { default S unshift(final T... obj) {
Stream<T> result = unwrap(); Stream<T> result = unwrap();
if (ArrayUtil.isNotEmpty(obj)) { if (ArrayUtil.isNotEmpty(obj)) {
@ -480,9 +491,10 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
Objects.requireNonNull(childrenGetter); Objects.requireNonNull(childrenGetter);
Objects.requireNonNull(childrenSetter); Objects.requireNonNull(childrenSetter);
final MutableObj<Function<T, EasyStream<T>>> recursiveRef = new MutableObj<>(); final MutableObj<Function<T, EasyStream<T>>> recursiveRef = new MutableObj<>();
@SuppressWarnings("unchecked")
final Function<T, EasyStream<T>> recursive = e -> EasyStream.of(childrenGetter.apply(e)) final Function<T, EasyStream<T>> recursive = e -> EasyStream.of(childrenGetter.apply(e))
.flat(recursiveRef.get()) .flat(recursiveRef.get())
.unshift(e); .unshift(e);
recursiveRef.set(recursive); recursiveRef.set(recursive);
return wrap(flatMap(recursive).peek(e -> childrenSetter.accept(e, null))); return wrap(flatMap(recursive).peek(e -> childrenSetter.accept(e, null)));
} }

View File

@ -269,6 +269,7 @@ public interface WrappedStream<T, S extends WrappedStream<T, S>> extends Stream<
@Override @Override
default <A> A[] toArray(final IntFunction<A[]> generator) { default <A> A[] toArray(final IntFunction<A[]> generator) {
Objects.requireNonNull(generator); Objects.requireNonNull(generator);
//noinspection SuspiciousToArrayCall
return unwrap().toArray(generator); return unwrap().toArray(generator);
} }
@ -547,7 +548,7 @@ public interface WrappedStream<T, S extends WrappedStream<T, S>> extends Stream<
* @return * @return
*/ */
@Override @Override
default S onClose(Runnable closeHandler) { default S onClose(final Runnable closeHandler) {
return wrap(unwrap().onClose(closeHandler)); return wrap(unwrap().onClose(closeHandler));
} }

View File

@ -0,0 +1,25 @@
package cn.hutool.core.text.dfa;
import org.junit.Assert;
import org.junit.Test;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class issueI5Q4HDTest {
@Test
public void matchAllTest(){
final String content="站房建设面积较小不符合规范要求。辅助设施_站房_面积";
final String keywordStr="不符合规范要求,现场手工比对孔不规范,采样口,现场,辅助设施,比对孔未处于监测断面下游,站房,未设置,标识,给排水,面积较小,监控设备,灭火装置,排污口,设备操作维护不方便,不规范,采样平台,参比方法,直爬梯,单独,站房建设,不健全,没有配置";
final List<String> keyWords = Arrays.asList(keywordStr.split(","));
final Set<String> keyWordSet=new HashSet<>(keyWords);
final WordTree wordTree=new WordTree();
wordTree.addWords(keyWordSet);
//DateUtil.beginOfHour()
final List<String> strings = wordTree.matchAll(content, -1, true, true);
Assert.assertEquals("[站房, 站房建设, 面积较小, 不符合规范要求, 辅助设施, 站房]", strings.toString());
}
}

View File

@ -31,6 +31,8 @@ public class SM2Test {
final KeyPair pair = KeyUtil.generateKeyPair("SM2"); final KeyPair pair = KeyUtil.generateKeyPair("SM2");
Assert.assertNotNull(pair.getPrivate()); Assert.assertNotNull(pair.getPrivate());
Assert.assertNotNull(pair.getPublic()); Assert.assertNotNull(pair.getPublic());
new SM2(pair.getPrivate(), pair.getPublic());
} }
@Test @Test
@ -319,4 +321,9 @@ public class SM2Test {
// 04占位一个字节 // 04占位一个字节
Assert.assertEquals(65, sm2.getQ(false).length); Assert.assertEquals(65, sm2.getQ(false).length);
} }
@Test
public void issuesI5PWQ4Test(){
}
} }

View File

@ -1022,6 +1022,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
* *
* @param <T> 结果类型 * @param <T> 结果类型
* @param function 响应内容处理函数 * @param function 响应内容处理函数
* @return 结果值
* @since 5.8.5 * @since 5.8.5
*/ */
public <T> T thenFunction(final Function<HttpResponse, T> function) { public <T> T thenFunction(final Function<HttpResponse, T> function) {

View File

@ -1,7 +1,10 @@
package cn.hutool.json; package cn.hutool.json;
import cn.hutool.core.bean.BeanPath; import cn.hutool.core.bean.BeanPath;
import cn.hutool.core.convert.ConvertException;
import cn.hutool.core.convert.Converter;
import cn.hutool.core.lang.mutable.MutableEntry; import cn.hutool.core.lang.mutable.MutableEntry;
import cn.hutool.json.convert.JSONConverter;
import java.io.Serializable; import java.io.Serializable;
import java.io.StringWriter; import java.io.StringWriter;
@ -14,7 +17,7 @@ import java.util.function.Predicate;
* *
* @author Looly * @author Looly
*/ */
public interface JSON extends Cloneable, Serializable { public interface JSON extends Converter, Cloneable, Serializable {
/** /**
* 获取JSON配置 * 获取JSON配置
@ -171,6 +174,11 @@ public interface JSON extends Cloneable, Serializable {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
default <T> T toBean(final Type type) { default <T> T toBean(final Type type) {
return (T) getConfig().getConverter().convert(type, this); return (T) convert(type, this);
}
@Override
default Object convert(Type targetType, Object value) throws ConvertException {
return JSONConverter.of(getConfig()).convert(targetType, value);
} }
} }

View File

@ -13,7 +13,6 @@ import cn.hutool.json.serialize.JSONWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.Writer; import java.io.Writer;
import java.lang.reflect.Type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
@ -231,11 +230,6 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
return this; return this;
} }
@Override
public <T> T toBean(final Type type) {
return JSON.super.toBean(type);
}
/** /**
* 根据给定名列表与其位置对应的值组成JSONObject * 根据给定名列表与其位置对应的值组成JSONObject
* *

View File

@ -1,10 +1,18 @@
package cn.hutool.json; package cn.hutool.json;
import cn.hutool.core.comparator.CompareUtil; import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.convert.Converter; import cn.hutool.core.convert.Converter;
import cn.hutool.core.convert.impl.DateConverter;
import cn.hutool.core.convert.impl.TemporalAccessorConverter;
import cn.hutool.core.reflect.TypeUtil;
import cn.hutool.core.text.StrUtil;
import cn.hutool.json.convert.JSONConverter;
import java.io.Serializable; import java.io.Serializable;
import java.time.temporal.TemporalAccessor;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date;
/** /**
* JSON配置项 * JSON配置项
@ -50,7 +58,33 @@ public class JSONConfig implements Serializable {
/** /**
* 自定义的类型转换器用于在序列化反序列化操作中实现对象类型转换 * 自定义的类型转换器用于在序列化反序列化操作中实现对象类型转换
*/ */
private Converter converter; private Converter converter = (type, value)->{
final Class<?> rawType = TypeUtil.getClass(type);
if(null == rawType){
return value;
}
if(JSON.class.isAssignableFrom(rawType)){
return JSONConverter.INSTANCE.toJSON(value);
}
if(Date.class.isAssignableFrom(rawType) || TemporalAccessor.class.isAssignableFrom(rawType)){
// 用户指定了日期格式获取日期属性时使用对应格式
final String valueStr = Convert.convertWithCheck(String.class, value, null, isIgnoreError());
if (null == valueStr) {
return null;
}
// 日期转换支持自定义日期格式
final String format = getDateFormat();
if (StrUtil.isNotBlank(format)) {
if (Date.class.isAssignableFrom(rawType)) {
return new DateConverter(format).convert(type, value);
} else {
return new TemporalAccessorConverter(format).convert(type, value);
}
}
}
return Convert.convertWithCheck(type, value, null, isIgnoreError());
};
/** /**
* 创建默认的配置项 * 创建默认的配置项

View File

@ -10,7 +10,6 @@ import cn.hutool.json.serialize.JSONWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.Writer; import java.io.Writer;
import java.lang.reflect.Type;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Collection; import java.util.Collection;
@ -150,11 +149,6 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
return this; return this;
} }
@Override
public <T> T toBean(final Type type) {
return JSON.super.toBean(type);
}
/** /**
* 将指定KEY列表的值组成新的JSONArray * 将指定KEY列表的值组成新的JSONArray
* *

View File

@ -1,6 +1,6 @@
package cn.hutool.json; package cn.hutool.json;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.copier.BeanCopier;
import cn.hutool.json.serialize.JSONDeserializer; import cn.hutool.json.serialize.JSONDeserializer;
import cn.hutool.json.serialize.JSONString; import cn.hutool.json.serialize.JSONString;
@ -28,8 +28,9 @@ public class JSONSupport implements JSONString, JSONDeserializer<Object> {
*/ */
@Override @Override
public Object deserialize(final JSON json) { public Object deserialize(final JSON json) {
// TODO 经过两次转换效率差待优化 BeanCopier.of(json,
BeanUtil.copyProperties(json.toBean(getClass()), this); this, this.getClass(),
InternalJSONUtil.toCopyOptions(json.getConfig())).copy();
return this; return this;
} }

View File

@ -141,7 +141,7 @@ public class JSONUtil {
* @return JSON * @return JSON
*/ */
public static JSON parse(final Object obj) { public static JSON parse(final Object obj) {
return JSONConverter.INSTANCE.convert(obj); return JSONConverter.INSTANCE.toJSON(obj);
} }
/** /**
@ -159,7 +159,7 @@ public class JSONUtil {
* @since 5.3.1 * @since 5.3.1
*/ */
public static JSON parse(final Object obj, final JSONConfig config) { public static JSON parse(final Object obj, final JSONConfig config) {
return JSONConverter.of(config).convert(obj); return JSONConverter.of(config).toJSON(obj);
} }
/** /**

View File

@ -1,16 +0,0 @@
package cn.hutool.json.convert;
import cn.hutool.core.convert.CompositeConverter;
import cn.hutool.core.convert.ConvertException;
import java.lang.reflect.Type;
public class JSONCompositeConverter extends CompositeConverter {
public static final JSONCompositeConverter INSTANCE = new JSONCompositeConverter();
@Override
public <T> T convert(final Type type, final Object value, final T defaultValue, final boolean isCustomFirst) throws ConvertException {
return super.convert(type, value, defaultValue, isCustomFirst);
}
}

View File

@ -1,18 +1,33 @@
package cn.hutool.json.convert; package cn.hutool.json.convert;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.BeanCopier;
import cn.hutool.core.convert.ConvertException; import cn.hutool.core.convert.ConvertException;
import cn.hutool.core.convert.Converter; import cn.hutool.core.convert.Converter;
import cn.hutool.core.convert.RegisterConverter;
import cn.hutool.core.convert.impl.ArrayConverter;
import cn.hutool.core.convert.impl.CollectionConverter;
import cn.hutool.core.convert.impl.MapConverter;
import cn.hutool.core.map.MapWrapper; import cn.hutool.core.map.MapWrapper;
import cn.hutool.core.reflect.ConstructorUtil;
import cn.hutool.core.reflect.TypeReference;
import cn.hutool.core.reflect.TypeUtil;
import cn.hutool.core.text.StrUtil; import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.json.InternalJSONUtil;
import cn.hutool.json.JSON; import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray; import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONConfig; import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONException;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import cn.hutool.json.serialize.GlobalSerializeMapping;
import cn.hutool.json.serialize.JSONDeserializer;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map;
/** /**
* JSON转换器实现Object对象转换为{@link JSON}支持的对象 * JSON转换器实现Object对象转换为{@link JSON}支持的对象
@ -28,6 +43,11 @@ import java.util.Iterator;
public class JSONConverter implements Converter { public class JSONConverter implements Converter {
public static final JSONConverter INSTANCE = new JSONConverter(null); public static final JSONConverter INSTANCE = new JSONConverter(null);
static {
RegisterConverter.getInstance().putCustom(JSONObject.class, INSTANCE);
RegisterConverter.getInstance().putCustom(JSONArray.class, INSTANCE);
}
/** /**
* 创建JSON转换器 * 创建JSON转换器
* *
@ -49,6 +69,30 @@ public class JSONConverter implements Converter {
this.config = config; this.config = config;
} }
@Override
public Object convert(Type targetType, final Object obj) throws ConvertException {
if (null == obj) {
return null;
}
// 对象转JSON
if (targetType instanceof JSON) {
return toJSON(obj);
}
// JSON转对象
if (obj instanceof JSON) {
if (targetType instanceof TypeReference) {
targetType = ((TypeReference<?>) targetType).getType();
}
return toBean(targetType, (JSON) obj);
}
// 无法转换
throw new JSONException("Can not convert from {}: [{}] to [{}]",
obj.getClass().getName(), obj, targetType.getTypeName());
}
/** /**
* 实现Object对象转换为{@link JSON}支持的对象 * 实现Object对象转换为{@link JSON}支持的对象
* <ul> * <ul>
@ -59,17 +103,9 @@ public class JSONConverter implements Converter {
* *
* @param obj 被转换的对象 * @param obj 被转换的对象
* @return 转换后的对象 * @return 转换后的对象
* @throws ConvertException 转换异常 * @throws JSONException 转换异常
*/ */
public JSON convert(final Object obj) throws ConvertException { public JSON toJSON(final Object obj) throws JSONException {
return (JSON) convert(null, obj);
}
@Override
public Object convert(final Type targetType, final Object obj) throws ConvertException {
if (null == obj) {
return null;
}
final JSON json; final JSON json;
if (obj instanceof JSON) { if (obj instanceof JSON) {
json = (JSON) obj; json = (JSON) obj;
@ -87,4 +123,99 @@ public class JSONConverter implements Converter {
return json; return json;
} }
@SuppressWarnings("unchecked")
private <T> T toBean(final Type targetType, final JSON json) {
final Class<T> rawType = (Class<T>) TypeUtil.getClass(targetType);
if(null != rawType && JSONDeserializer.class.isAssignableFrom(rawType)){
return (T) JSONDeserializerConverter.INSTANCE.convert(targetType, json);
}
// 全局自定义反序列化优先级低于实现JSONDeserializer接口
final JSONDeserializer<?> deserializer = GlobalSerializeMapping.getDeserializer(targetType);
if (null != deserializer) {
return (T) deserializer.deserialize(json);
}
// 其他转换不支持非Class的泛型类型
if (null == rawType) {
throw new JSONException("Can not get class from type: {}", targetType);
}
// 特殊类型转换包括CollectionMap强转Array等
final T result = toSpecial(targetType, rawType, json);
if (null != result) {
return result;
}
// 标准转换器
final Converter converter = RegisterConverter.getInstance().getConverter(targetType, true);
if (null != converter) {
return (T) converter.convert(targetType, json);
}
// 尝试转Bean
if (BeanUtil.isBean(rawType)) {
return BeanCopier.of(json,
ConstructorUtil.newInstanceIfPossible(rawType), targetType,
InternalJSONUtil.toCopyOptions(json.getConfig())).copy();
}
// 跳过异常时返回null
if(json.getConfig().isIgnoreError()){
return null;
}
// 无法转换
throw new JSONException("Can not convert from {}: [{}] to [{}]",
json.getClass().getName(), json, targetType.getTypeName());
}
// ----------------------------------------------------------- Private method start
/**
* 特殊类型转换<br>
* 包括
*
* <pre>
* Collection
* Map
* 强转无需转换
* 数组
* </pre>
*
* @param <T> 转换的目标类型转换器转换到的类型
* @param type 类型
* @param value
* @return 转换后的值
*/
@SuppressWarnings("unchecked")
private <T> T toSpecial(final Type type, final Class<T> rowType, final JSON value) {
if (null == rowType) {
return null;
}
// 集合转换含有泛型参数不可以默认强转
if (Collection.class.isAssignableFrom(rowType)) {
return (T) CollectionConverter.INSTANCE.convert(type, value);
}
// Map类型含有泛型参数不可以默认强转
if (Map.class.isAssignableFrom(rowType)) {
return (T) MapConverter.INSTANCE.convert(type, value);
}
// 默认强转
if (rowType.isInstance(value)) {
return (T) value;
}
// 数组转换
if (rowType.isArray()) {
return (T) ArrayConverter.INSTANCE.convert(type, value);
}
// 表示非需要特殊转换的对象
return null;
}
// ----------------------------------------------------------- Private method end
} }

View File

@ -15,6 +15,8 @@ import cn.hutool.json.serialize.JSONDeserializer;
public class JSONDeserializerConverter extends AbstractConverter { public class JSONDeserializerConverter extends AbstractConverter {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public static final JSONDeserializerConverter INSTANCE = new JSONDeserializerConverter();
@Override @Override
protected Object convertInternal(final Class<?> targetClass, final Object value) { protected Object convertInternal(final Class<?> targetClass, final Object value) {
// 自定义反序列化 // 自定义反序列化

View File

@ -1,3 +1,5 @@
package cn.hutool.json;
import cn.hutool.json.JSON; import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;

View File

@ -472,7 +472,7 @@ public class JSONObjectTest {
@Test @Test
public void setDateFormatTest3() { public void setDateFormatTest3() {
// 自定义格式为只有秒的时间戳用于JWT // 自定义格式为只有秒的时间戳用于JWT
final JSONConfig jsonConfig = JSONConfig.of().setDateFormat("#sss"); final JSONConfig jsonConfig = JSONConfig.of().setDateFormat("#sss");
final Date date = DateUtil.parse("2020-06-05 11:16:11"); final Date date = DateUtil.parse("2020-06-05 11:16:11");

View File

@ -0,0 +1,18 @@
package cn.hutool.poi.excel;
import cn.hutool.core.lang.Console;
import org.junit.Ignore;
import org.junit.Test;
import java.util.List;
public class IssueI5Q1TWTest {
@Test
@Ignore
public void readTest(){
final ExcelReader reader = ExcelUtil.getReader("d:/test/I5Q1TW.xlsx");
final List<List<Object>> read = reader.read();
Console.log(reader.readCellValue(0, 0));
}
}