mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
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:
commit
814b55cc87
@ -98,20 +98,22 @@ public class CompositeConverter extends RegisterConverter {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
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)) {
|
||||
return defaultValue;
|
||||
}
|
||||
if (TypeUtil.isUnknown(type)) {
|
||||
// 对于用户不指定目标类型的情况,返回原值
|
||||
if(null == defaultValue){
|
||||
throw new ConvertException("Unsupported convert to unKnow type: {}", type);
|
||||
return (T) value;
|
||||
}
|
||||
type = defaultValue.getClass();
|
||||
}
|
||||
|
||||
// value本身实现了Converter接口,直接调用
|
||||
if(value instanceof Converter){
|
||||
return ((Converter) value).convert(type, value, defaultValue);
|
||||
}
|
||||
|
||||
if (type instanceof TypeReference) {
|
||||
type = ((TypeReference<?>) type).getType();
|
||||
}
|
||||
|
@ -29,9 +29,6 @@ import cn.hutool.core.convert.impl.XMLGregorianCalendarConverter;
|
||||
import cn.hutool.core.convert.impl.ZoneIdConverter;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
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 java.io.Serializable;
|
||||
@ -78,6 +75,25 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
public class RegisterConverter implements Converter, Serializable {
|
||||
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() {
|
||||
registerDefault();
|
||||
registerCustomBySpi();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -233,20 +248,4 @@ public class RegisterConverter implements Converter, Serializable {
|
||||
defaultConverterMap.put(Optional.class, new OptionalConverter());// since 5.0.0
|
||||
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) {
|
||||
// 忽略注册失败的
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +57,11 @@ public class BeanConverter implements Converter, Serializable {
|
||||
return null;
|
||||
}
|
||||
|
||||
// value本身实现了Converter接口,直接调用
|
||||
if(value instanceof Converter){
|
||||
return ((Converter) value).convert(targetType, value);
|
||||
}
|
||||
|
||||
Class<?> targetClass = TypeUtil.getClass(targetType);
|
||||
Assert.notNull(targetClass, "Target type is not a class!");
|
||||
|
||||
@ -79,6 +84,6 @@ public class BeanConverter implements Converter, Serializable {
|
||||
return SerializeUtil.deserialize((byte[]) value);
|
||||
}
|
||||
|
||||
throw new ConvertException("Unsupported source type: {}", value.getClass());
|
||||
throw new ConvertException("Unsupported source type: [{}] to [{}]", value.getClass(), targetType);
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ public class DateConverter extends AbstractConverter {
|
||||
return wrap(targetClass, DateUtil.date((TemporalAccessor) value));
|
||||
} else if (value instanceof Calendar) {
|
||||
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());
|
||||
} else {
|
||||
// 统一按照字符串处理
|
||||
|
@ -67,7 +67,7 @@ public class MapConverter implements Converter, Serializable {
|
||||
// 二次转换,转换键值类型
|
||||
map = convert(targetType, keyType, valueType, map);
|
||||
} 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;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ public interface SerBiConsumer<T, U> extends BiConsumer<T, U>, Serializable {
|
||||
* @return lambda
|
||||
*/
|
||||
@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) -> {});
|
||||
}
|
||||
|
||||
@ -32,9 +32,8 @@ public interface SerBiConsumer<T, U> extends BiConsumer<T, U>, Serializable {
|
||||
*
|
||||
* @param t the first 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;
|
||||
|
||||
/**
|
||||
@ -44,10 +43,10 @@ public interface SerBiConsumer<T, U> extends BiConsumer<T, U>, Serializable {
|
||||
* @param u the second input argument
|
||||
*/
|
||||
@Override
|
||||
default void accept(T t, U u) {
|
||||
default void accept(final T t, final U u) {
|
||||
try {
|
||||
accepting(t, u);
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception 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
|
||||
* @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);
|
||||
return (l, r) -> {
|
||||
accepting(l, r);
|
||||
|
@ -21,9 +21,8 @@ public interface SerBiFunction<T, U, R> extends BiFunction<T, U, R>, Serializabl
|
||||
* @param t the first function argument
|
||||
* @param u the second function argument
|
||||
* @return the function result
|
||||
* @throws Exception wrappered checked exceptions
|
||||
* @throws Exception wrapped checked exceptions
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
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
|
||||
*/
|
||||
@Override
|
||||
default R apply(T t, U u) {
|
||||
default R apply(final T t, final U u) {
|
||||
try {
|
||||
return this.applying(t, u);
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception 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
|
||||
* @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);
|
||||
return (T t, U u) -> after.apply(this.apply(t, u));
|
||||
}
|
||||
|
@ -23,9 +23,8 @@ public interface SerBiPredicate<T, U> extends BiPredicate<T, U>, Serializable {
|
||||
* @param u the second input argument
|
||||
* @return {@code true} if the input arguments match the predicate,
|
||||
* otherwise {@code false}
|
||||
* @throws Exception wrappered checked exceptions
|
||||
* @throws Exception wrapped checked exceptions
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
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}
|
||||
*/
|
||||
@Override
|
||||
default boolean test(T t, U u) {
|
||||
default boolean test(final T t, final U u) {
|
||||
try {
|
||||
return testing(t, u);
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception 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
|
||||
* @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);
|
||||
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
|
||||
* @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);
|
||||
return (T t, U u) -> test(t, u) || other.test(t, u);
|
||||
}
|
||||
|
@ -22,9 +22,8 @@ public interface SerBinaryOperator<T> extends BinaryOperator<T>, Serializable {
|
||||
* @param t the first function argument
|
||||
* @param u the second function argument
|
||||
* @return the function result
|
||||
* @throws Exception wrappered checked exceptions
|
||||
* @throws Exception wrapped checked exceptions
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
T applying(T t, T u) throws Exception;
|
||||
|
||||
/**
|
||||
@ -35,10 +34,10 @@ public interface SerBinaryOperator<T> extends BinaryOperator<T>, Serializable {
|
||||
* @return the function result
|
||||
*/
|
||||
@Override
|
||||
default T apply(T t, T u) {
|
||||
default T apply(final T t, final T u) {
|
||||
try {
|
||||
return this.applying(t, u);
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
throw new UtilException(e);
|
||||
}
|
||||
}
|
||||
@ -53,7 +52,7 @@ public interface SerBinaryOperator<T> extends BinaryOperator<T>, Serializable {
|
||||
* according to the supplied {@code Comparator}
|
||||
* @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);
|
||||
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}
|
||||
* @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);
|
||||
return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
|
||||
}
|
||||
|
@ -20,9 +20,8 @@ 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
|
||||
* @throws Exception wrapped checked exceptions
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
void accepting(T t) throws Exception;
|
||||
|
||||
/**
|
||||
@ -31,10 +30,10 @@ public interface SerConsumer<T> extends Consumer<T>, Serializable {
|
||||
* @param t the input argument
|
||||
*/
|
||||
@Override
|
||||
default void accept(T t) {
|
||||
default void accept(final T t) {
|
||||
try {
|
||||
accepting(t);
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
throw new UtilException(e);
|
||||
}
|
||||
}
|
||||
@ -47,7 +46,7 @@ public interface SerConsumer<T> extends Consumer<T>, Serializable {
|
||||
* @return lambda
|
||||
*/
|
||||
@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 -> {});
|
||||
}
|
||||
|
||||
@ -63,7 +62,7 @@ public interface SerConsumer<T> extends Consumer<T>, Serializable {
|
||||
* operation followed by the {@code after} operation
|
||||
* @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);
|
||||
return (T t) -> {
|
||||
accept(t);
|
||||
|
@ -23,9 +23,8 @@ public interface SerConsumer3<P1, P2, P3> extends Serializable {
|
||||
* @param p1 参数一
|
||||
* @param p2 参数二
|
||||
* @param p3 参数三
|
||||
* @throws Exception wrappered checked exceptions
|
||||
* @throws Exception wrapped checked exceptions
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
void accepting(P1 p1, P2 p2, P3 p3) throws Exception;
|
||||
|
||||
/**
|
||||
|
@ -19,9 +19,8 @@ public interface SerFunction<T, R> extends Function<T, R>, Serializable {
|
||||
*
|
||||
* @param t the function argument
|
||||
* @return the function result
|
||||
* @throws Exception wrappered checked exceptions
|
||||
* @throws Exception wrapped checked exceptions
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
R applying(T t) throws Exception;
|
||||
|
||||
/**
|
||||
|
@ -22,7 +22,7 @@ public interface SerPredicate<T> extends Predicate<T>, Serializable {
|
||||
* @param t the input argument
|
||||
* @return {@code true} if the input argument matches the predicate,
|
||||
* otherwise {@code false}
|
||||
* @throws Exception wrappered checked exceptions
|
||||
* @throws Exception wrapped checked exceptions
|
||||
*/
|
||||
boolean testing(T t) throws Exception;
|
||||
|
||||
@ -34,10 +34,10 @@ public interface SerPredicate<T> extends Predicate<T>, Serializable {
|
||||
* otherwise {@code false}
|
||||
*/
|
||||
@Override
|
||||
default boolean test(T t) {
|
||||
default boolean test(final T t) {
|
||||
try {
|
||||
return testing(t);
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
throw new UtilException(e);
|
||||
}
|
||||
}
|
||||
@ -50,7 +50,7 @@ public interface SerPredicate<T> extends Predicate<T>, Serializable {
|
||||
* @return lambda
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ public interface SerPredicate<T> extends Predicate<T>, Serializable {
|
||||
* @return lambda
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ public interface SerPredicate<T> extends Predicate<T>, Serializable {
|
||||
* @return a predicate that tests if two arguments are equal according
|
||||
* to {@link Objects#equals(Object, Object)}
|
||||
*/
|
||||
static <T> SerPredicate<T> isEqual(Object... targetRef) {
|
||||
static <T> SerPredicate<T> isEqual(final Object... targetRef) {
|
||||
return (null == targetRef)
|
||||
? Objects::isNull
|
||||
: 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
|
||||
* @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);
|
||||
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
|
||||
* @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);
|
||||
return t -> test(t) || other.test(t);
|
||||
}
|
||||
|
@ -24,10 +24,9 @@ public interface SerRunnable extends Runnable, Serializable {
|
||||
* The general contract of the method <code>run</code> is that it may
|
||||
* take any action whatsoever.
|
||||
*
|
||||
* @throws Exception wrappered checked exceptions
|
||||
* @throws Exception wrapped checked exceptions
|
||||
* @see Thread#run()
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
void running() throws Exception;
|
||||
|
||||
/**
|
||||
@ -45,7 +44,7 @@ public interface SerRunnable extends Runnable, Serializable {
|
||||
default void run() {
|
||||
try {
|
||||
running();
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
throw new UtilException(e);
|
||||
}
|
||||
}
|
||||
@ -56,7 +55,7 @@ public interface SerRunnable extends Runnable, Serializable {
|
||||
* @param serRunnableArray lambda
|
||||
* @return lambda
|
||||
*/
|
||||
static SerRunnable multi(SerRunnable... serRunnableArray) {
|
||||
static SerRunnable multi(final SerRunnable... serRunnableArray) {
|
||||
return () -> Stream.of(serRunnableArray).forEach(SerRunnable::run);
|
||||
}
|
||||
|
||||
|
@ -19,9 +19,8 @@ public interface SerSupplier<T> extends Supplier<T>, Serializable {
|
||||
* Gets a result.
|
||||
*
|
||||
* @return a result
|
||||
* @throws Exception wrappered checked exceptions
|
||||
* @throws Exception wrapped checked exceptions
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
T getting() throws Exception;
|
||||
|
||||
/**
|
||||
@ -33,7 +32,7 @@ public interface SerSupplier<T> extends Supplier<T>, Serializable {
|
||||
default T get() {
|
||||
try {
|
||||
return getting();
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
throw new UtilException(e);
|
||||
}
|
||||
}
|
||||
@ -46,7 +45,7 @@ public interface SerSupplier<T> extends Supplier<T>, Serializable {
|
||||
* @return lambda
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
|
||||
|
@ -20,9 +20,8 @@ public interface SerUnaryOperator<T> extends UnaryOperator<T>, Serializable {
|
||||
*
|
||||
* @param t the function argument
|
||||
* @return the function result
|
||||
* @throws Exception wrappered checked exceptions
|
||||
* @throws Exception wrapped checked exceptions
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
T applying(T t) throws Exception;
|
||||
|
||||
/**
|
||||
@ -32,10 +31,10 @@ public interface SerUnaryOperator<T> extends UnaryOperator<T>, Serializable {
|
||||
* @return the function result
|
||||
*/
|
||||
@Override
|
||||
default T apply(T t) {
|
||||
default T apply(final T t) {
|
||||
try {
|
||||
return applying(t);
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
throw new UtilException(e);
|
||||
}
|
||||
}
|
||||
@ -61,7 +60,7 @@ public interface SerUnaryOperator<T> extends UnaryOperator<T>, Serializable {
|
||||
* @return identity after casting
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
|
||||
|
@ -7,10 +7,11 @@ import cn.hutool.core.collection.SetUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.exceptions.CloneRuntimeException;
|
||||
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.SerSupplier;
|
||||
import cn.hutool.core.lang.getter.BasicTypeGetter;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.sql.Time;
|
||||
@ -564,7 +565,7 @@ public class Dict extends CustomKeyMap<String, Object> implements BasicTypeGette
|
||||
* @see BeanPath#get(Object)
|
||||
* @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));
|
||||
}
|
||||
// -------------------------------------------------------------------- Get end
|
||||
@ -573,7 +574,7 @@ public class Dict extends CustomKeyMap<String, Object> implements BasicTypeGette
|
||||
public Dict clone() {
|
||||
try {
|
||||
return (Dict) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
} catch (final CloneNotSupportedException e) {
|
||||
throw new CloneRuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
@ -342,7 +342,7 @@ public class EasyStream<T> extends AbstractEnhancedWrappedStream<T, EasyStream<T
|
||||
Objects.requireNonNull(pIdValuesMap);
|
||||
final MutableObj<Consumer<List<T>>> recursiveRef = new MutableObj<>();
|
||||
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);
|
||||
recursiveRef.get().accept(children);
|
||||
});
|
||||
|
@ -17,52 +17,52 @@ import java.util.stream.Stream;
|
||||
*
|
||||
* @param <T> 流中的元素类型
|
||||
* @param <S> {@link TerminableWrappedStream}的实现类类型
|
||||
* @author huangchengxing VampireAchao
|
||||
* @author huangchengxing
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public interface TerminableWrappedStream<T, S extends TerminableWrappedStream<T, S>> extends WrappedStream<T, S> {
|
||||
|
||||
// region ============ to collection ============
|
||||
// region ============ to collection ============
|
||||
|
||||
/**
|
||||
* 转换为{@link ArrayList}
|
||||
*
|
||||
* @return 集合
|
||||
/**
|
||||
* 转换为{@link ArrayList}
|
||||
*
|
||||
* @return 集合
|
||||
* @see #toColl(Supplier)
|
||||
*/
|
||||
default List<T> toList() {
|
||||
return this.toColl(ArrayList::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* 换为不可变集合
|
||||
*
|
||||
* @return 集合
|
||||
* @see #toColl(Supplier)
|
||||
*/
|
||||
default List<T> toList() {
|
||||
return this.toColl(ArrayList::new);
|
||||
}
|
||||
default List<T> toUnmodifiableList() {
|
||||
return Collections.unmodifiableList(this.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 换为不可变集合
|
||||
*
|
||||
* @return 集合
|
||||
/**
|
||||
* 转换为HashSet
|
||||
*
|
||||
* @return 集合
|
||||
* @see #toColl(Supplier)
|
||||
*/
|
||||
default List<T> toUnmodifiableList() {
|
||||
return Collections.unmodifiableList(this.toList());
|
||||
}
|
||||
default Set<T> toSet() {
|
||||
return this.toColl(HashSet::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为HashSet
|
||||
*
|
||||
* @return 集合
|
||||
/**
|
||||
* 换为不可变集合
|
||||
*
|
||||
* @return 集合
|
||||
* @see #toColl(Supplier)
|
||||
*/
|
||||
default Set<T> toSet() {
|
||||
return this.toColl(HashSet::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* 换为不可变集合
|
||||
*
|
||||
* @return 集合
|
||||
* @see #toColl(Supplier)
|
||||
*/
|
||||
default Set<T> toUnmodifiableSet() {
|
||||
return Collections.unmodifiableSet(this.toSet());
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
// endregion
|
||||
// endregion
|
||||
|
||||
// region ============ to map ============
|
||||
// region ============ to map ============
|
||||
|
||||
/**
|
||||
* 转换为map,key为给定操作执行后的返回值,value为当前元素
|
||||
*
|
||||
* @param keyMapper 指定的key操作
|
||||
* @param <K> key类型
|
||||
* @return map
|
||||
/**
|
||||
* 转换为map,key为给定操作执行后的返回值,value为当前元素
|
||||
*
|
||||
* @param keyMapper 指定的key操作
|
||||
* @param <K> key类型
|
||||
* @return map
|
||||
* @see #toMap(Function, Function, BinaryOperator, Supplier)
|
||||
*/
|
||||
default <K> Map<K, T> toMap(final Function<? super T, ? extends K> keyMapper) {
|
||||
return this.toMap(keyMapper, Function.identity());
|
||||
}
|
||||
*/
|
||||
default <K> Map<K, T> toMap(final Function<? super T, ? extends K> keyMapper) {
|
||||
return this.toMap(keyMapper, Function.identity());
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为map,key,value为给定操作执行后的返回值
|
||||
*
|
||||
* @param keyMapper 指定的key操作
|
||||
* @param valueMapper 指定value操作
|
||||
* @param <K> key类型
|
||||
* @param <U> value类型
|
||||
* @return map
|
||||
/**
|
||||
* 转换为map,key,value为给定操作执行后的返回值
|
||||
*
|
||||
* @param keyMapper 指定的key操作
|
||||
* @param valueMapper 指定value操作
|
||||
* @param <K> key类型
|
||||
* @param <U> value类型
|
||||
* @return map
|
||||
* @see #toMap(Function, Function, BinaryOperator, Supplier)
|
||||
*/
|
||||
default <K, U> Map<K, U> toMap(
|
||||
final Function<? super T, ? extends K> keyMapper, final Function<? super T, ? extends U> valueMapper) {
|
||||
return this.toMap(keyMapper, valueMapper, (l, r) -> r);
|
||||
}
|
||||
*/
|
||||
default <K, U> Map<K, U> toMap(
|
||||
final Function<? super T, ? extends K> keyMapper, final Function<? super T, ? extends U> valueMapper) {
|
||||
return this.toMap(keyMapper, valueMapper, (l, r) -> r);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为不可变map,key,value为给定操作执行后的返回值
|
||||
*
|
||||
* @param keyMapper 指定的key操作
|
||||
* @param valueMapper 指定value操作
|
||||
* @param <K> key类型
|
||||
* @param <U> value类型
|
||||
* @return map
|
||||
/**
|
||||
* 转换为不可变map,key,value为给定操作执行后的返回值
|
||||
*
|
||||
* @param keyMapper 指定的key操作
|
||||
* @param valueMapper 指定value操作
|
||||
* @param <K> key类型
|
||||
* @param <U> value类型
|
||||
* @return map
|
||||
* @see #toMap(Function, Function, BinaryOperator, Supplier)
|
||||
*/
|
||||
default <K, U> Map<K, U> toUnmodifiableMap(
|
||||
final Function<? super T, ? extends K> keyMapper, final Function<? super T, ? extends U> valueMapper) {
|
||||
return Collections.unmodifiableMap(this.toMap(keyMapper, valueMapper));
|
||||
}
|
||||
*/
|
||||
default <K, U> Map<K, U> toUnmodifiableMap(
|
||||
final Function<? super T, ? extends K> keyMapper, final Function<? super T, ? extends U> valueMapper) {
|
||||
return Collections.unmodifiableMap(this.toMap(keyMapper, valueMapper));
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为map,key,value为给定操作执行后的返回值
|
||||
*
|
||||
* @param keyMapper 指定的key操作
|
||||
* @param valueMapper 指定value操作
|
||||
* @param mergeFunction 合并操作
|
||||
* @param <K> key类型
|
||||
* @param <U> value类型
|
||||
* @return map
|
||||
/**
|
||||
* 转换为map,key,value为给定操作执行后的返回值
|
||||
*
|
||||
* @param keyMapper 指定的key操作
|
||||
* @param valueMapper 指定value操作
|
||||
* @param mergeFunction 合并操作
|
||||
* @param <K> key类型
|
||||
* @param <U> value类型
|
||||
* @return map
|
||||
* @see #toMap(Function, Function, BinaryOperator, Supplier)
|
||||
*/
|
||||
default <K, U> Map<K, U> toMap(
|
||||
final Function<? super T, ? extends K> keyMapper,
|
||||
final Function<? super T, ? extends U> valueMapper,
|
||||
final BinaryOperator<U> mergeFunction) {
|
||||
return this.toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
|
||||
}
|
||||
*/
|
||||
default <K, U> Map<K, U> toMap(
|
||||
final Function<? super T, ? extends K> keyMapper,
|
||||
final Function<? super T, ? extends U> valueMapper,
|
||||
final BinaryOperator<U> mergeFunction) {
|
||||
return this.toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为不可变map,key,value为给定操作执行后的返回值
|
||||
*
|
||||
* @param keyMapper 指定的key操作
|
||||
* @param valueMapper 指定value操作
|
||||
* @param mergeFunction 合并操作
|
||||
* @param <K> key类型
|
||||
* @param <U> value类型
|
||||
* @return map
|
||||
/**
|
||||
* 转换为不可变map,key,value为给定操作执行后的返回值
|
||||
*
|
||||
* @param keyMapper 指定的key操作
|
||||
* @param valueMapper 指定value操作
|
||||
* @param mergeFunction 合并操作
|
||||
* @param <K> key类型
|
||||
* @param <U> value类型
|
||||
* @return map
|
||||
* @see #toMap(Function, Function, BinaryOperator, Supplier)
|
||||
*/
|
||||
default <K, U> Map<K, U> toUnmodifiableMap(
|
||||
final Function<? super T, ? extends K> keyMapper,
|
||||
final Function<? super T, ? extends U> valueMapper,
|
||||
final BinaryOperator<U> mergeFunction) {
|
||||
return Collections.unmodifiableMap(
|
||||
this.toMap(keyMapper, valueMapper, mergeFunction, HashMap::new)
|
||||
*/
|
||||
default <K, U> Map<K, U> toUnmodifiableMap(
|
||||
final Function<? super T, ? extends K> keyMapper,
|
||||
final Function<? super T, ? extends U> valueMapper,
|
||||
final BinaryOperator<U> mergeFunction) {
|
||||
return Collections.unmodifiableMap(
|
||||
this.toMap(keyMapper, valueMapper, mergeFunction, HashMap::new)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为map,key,value为给定操作执行后的返回值
|
||||
*
|
||||
* @param keyMapper 指定的key操作
|
||||
* @param valueMapper 指定value操作
|
||||
* @param mergeFunction 合并操作
|
||||
* @param mapSupplier map工厂
|
||||
* @param <K> key类型
|
||||
* @param <U> value类型
|
||||
* @param <M> map类型
|
||||
* @return map
|
||||
*/
|
||||
default <K, U, M extends Map<K, U>> M toMap(
|
||||
/**
|
||||
* 转换为map,key,value为给定操作执行后的返回值
|
||||
*
|
||||
* @param keyMapper 指定的key操作
|
||||
* @param valueMapper 指定value操作
|
||||
* @param mergeFunction 合并操作
|
||||
* @param mapSupplier map工厂
|
||||
* @param <K> key类型
|
||||
* @param <U> value类型
|
||||
* @param <M> map类型
|
||||
* @return map
|
||||
*/
|
||||
default <K, U, M extends Map<K, U>> M toMap(
|
||||
final Function<? super T, ? extends K> keyMapper,
|
||||
final Function<? super T, ? extends U> valueMapper,
|
||||
final BinaryOperator<U> mergeFunction,
|
||||
Supplier<M> mapSupplier) {
|
||||
final Supplier<M> mapSupplier) {
|
||||
Objects.requireNonNull(keyMapper);
|
||||
Objects.requireNonNull(valueMapper);
|
||||
Objects.requireNonNull(mergeFunction);
|
||||
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 ============
|
||||
|
||||
/**
|
||||
* 与给定的可迭代对象转换成map,key为现有元素,value为给定可迭代对象迭代的元素<br>
|
||||
* 至少包含全部的key,如果对应位置上的value不存在,则为null
|
||||
*
|
||||
* @param other 可迭代对象
|
||||
* @param <R> 可迭代对象迭代的元素类型
|
||||
* @return map,key为现有元素,value为给定可迭代对象迭代的元素;<br>
|
||||
* 至少包含全部的key,如果对应位置上的value不存在,则为null;<br>
|
||||
* 如果key重复, 则保留最后一个关联的value;<br>
|
||||
*/
|
||||
default <R> Map<T, R> toZip(final Iterable<R> other) {
|
||||
/**
|
||||
* 与给定的可迭代对象转换成map,key为现有元素,value为给定可迭代对象迭代的元素<br>
|
||||
* 至少包含全部的key,如果对应位置上的value不存在,则为null
|
||||
*
|
||||
* @param other 可迭代对象
|
||||
* @param <R> 可迭代对象迭代的元素类型
|
||||
* @return map,key为现有元素,value为给定可迭代对象迭代的元素;<br>
|
||||
* 至少包含全部的key,如果对应位置上的value不存在,则为null;<br>
|
||||
* 如果key重复, 则保留最后一个关联的value;<br>
|
||||
*/
|
||||
default <R> Map<T, R> toZip(final Iterable<R> other) {
|
||||
Objects.requireNonNull(other);
|
||||
// value对象迭代器
|
||||
final Iterator<R> iterator = Opt.ofNullable(other).map(Iterable::iterator).orElseGet(Collections::emptyIterator);
|
||||
if (this.isParallel()) {
|
||||
// value对象迭代器
|
||||
final Iterator<R> iterator = Opt.ofNullable(other).map(Iterable::iterator).orElseGet(Collections::emptyIterator);
|
||||
if (this.isParallel()) {
|
||||
final List<T> keyList = toList();
|
||||
final Map<T, R> map = new HashMap<>(keyList.size());
|
||||
for (T key : keyList) {
|
||||
map.put(key, iterator.hasNext() ? iterator.next() : null);
|
||||
}
|
||||
return map;
|
||||
} else {
|
||||
return this.toMap(Function.identity(), e -> iterator.hasNext() ? iterator.next() : null);
|
||||
}
|
||||
}
|
||||
final Map<T, R> map = new HashMap<>(keyList.size());
|
||||
for (final T key : keyList) {
|
||||
map.put(key, iterator.hasNext() ? iterator.next() : null);
|
||||
}
|
||||
return map;
|
||||
} else {
|
||||
return this.toMap(Function.identity(), e -> iterator.hasNext() ? iterator.next() : null);
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
// endregion
|
||||
|
||||
// region ============ to optional ============
|
||||
|
||||
@ -408,7 +408,7 @@ public interface TerminableWrappedStream<T, S extends TerminableWrappedStream<T,
|
||||
* @see #group(Function, Supplier, Collector)
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
@ -426,9 +426,9 @@ public interface TerminableWrappedStream<T, S extends TerminableWrappedStream<T,
|
||||
* @see CollectorUtil#groupingBy(Function, Supplier, Collector)
|
||||
*/
|
||||
default <K, D, A, M extends Map<K, D>> M group(
|
||||
final Function<? super T, ? extends K> classifier,
|
||||
final Supplier<M> mapFactory,
|
||||
final Collector<? super T, A, D> downstream) {
|
||||
final Function<? super T, ? extends K> classifier,
|
||||
final Supplier<M> mapFactory,
|
||||
final Collector<? super T, A, D> downstream) {
|
||||
Objects.requireNonNull(classifier);
|
||||
Objects.requireNonNull(mapFactory);
|
||||
Objects.requireNonNull(downstream);
|
||||
@ -449,9 +449,9 @@ public interface TerminableWrappedStream<T, S extends TerminableWrappedStream<T,
|
||||
/**
|
||||
* 根据给定判断条件分组
|
||||
*
|
||||
* @param predicate 判断条件
|
||||
* @param <C> 值类型
|
||||
* @param predicate 判断条件
|
||||
* @param collFactory 提供的集合
|
||||
* @param <C> 集合类型
|
||||
* @return map
|
||||
* @see #partition(Predicate, Collector)
|
||||
*/
|
||||
@ -464,7 +464,7 @@ public interface TerminableWrappedStream<T, S extends TerminableWrappedStream<T,
|
||||
*
|
||||
* @param predicate 判断条件
|
||||
* @param downstream 下游操作
|
||||
* @param <R> 返回值类型
|
||||
* @param <R> 返回值类型
|
||||
* @return map
|
||||
*/
|
||||
default <R> Map<Boolean, R> partition(final Predicate<T> predicate, final Collector<T, ?, R> downstream) {
|
||||
|
@ -3,6 +3,7 @@ package cn.hutool.core.stream;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.collection.iter.IterUtil;
|
||||
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.MutableObj;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
@ -23,7 +24,7 @@ import java.util.stream.StreamSupport;
|
||||
*
|
||||
* @param <T> 流中的元素类型
|
||||
* @param <S> {@link TransformableWrappedStream}的实现类类型
|
||||
* @author huangchengxing VampireAchao
|
||||
* @author huangchengxing
|
||||
* @since 6.0.0
|
||||
*/
|
||||
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 合并后的结果对象的流
|
||||
*/
|
||||
default <U, R> EasyStream<R> zip(
|
||||
final Iterable<U> other,
|
||||
final BiFunction<? super T, ? super U, ? extends R> zipper) {
|
||||
final Iterable<U> other,
|
||||
final BiFunction<? super T, ? super U, ? extends R> zipper) {
|
||||
Objects.requireNonNull(zipper);
|
||||
Map<Integer, T> idxIdentityMap = mapIdx((e, idx) -> MapUtil.entry(idx, e)).collect(CollectorUtil.entryToMap());
|
||||
Map<Integer, U> idxOtherMap = EasyStream.of(other).mapIdx((e, idx) -> MapUtil.entry(idx, e)).collect(CollectorUtil.entryToMap());
|
||||
if (idxIdentityMap.size() <= idxOtherMap.size()) {
|
||||
return EasyStream.of(idxIdentityMap.keySet(), isParallel()).map(k -> zipper.apply(idxIdentityMap.get(k), idxOtherMap.get(k)));
|
||||
final Spliterator<T> keys = spliterator();
|
||||
final Spliterator<U> values = Opt.ofNullable(other).map(Iterable::spliterator).orElseGet(Spliterators::emptySpliterator);
|
||||
// 获取两个Spliterator的中较小的数量
|
||||
// 如果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.iterate(0, i -> i < size, i -> i + batchSize)
|
||||
.map(skip -> EasyStream.of(list.subList(skip, Math.min(size, skip + batchSize)), isParallel()))
|
||||
.parallel(isParallel())
|
||||
.onClose(unwrap()::close);
|
||||
.map(skip -> EasyStream.of(list.subList(skip, Math.min(size, skip + batchSize)), isParallel()))
|
||||
.parallel(isParallel())
|
||||
.onClose(unwrap()::close);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -104,8 +114,8 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
|
||||
/**
|
||||
* 将当前流转为键值对流
|
||||
*
|
||||
* @param keyMapper 键的映射方法
|
||||
* @param <K> 键类型
|
||||
* @param keyMapper 键的映射方法
|
||||
* @param <K> 键类型
|
||||
* @return {@link EntryStream}实例
|
||||
*/
|
||||
default <K> EntryStream<K, T> toEntries(final Function<T, K> keyMapper) {
|
||||
@ -145,10 +155,11 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
|
||||
* @param items 放入值
|
||||
* @return 操作后的流
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
default S splice(final int start, final int deleteCount, final T... items) {
|
||||
final List<T> elements = unwrap().collect(Collectors.toList());
|
||||
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:
|
||||
* <pre>{@code
|
||||
* EasyStream.of(1, 2, 3, 4, 5)
|
||||
* .dropWhile(i -> !Objects.equals(3, i)) // 删除不为3的元素,一直到遇到第一个3为止
|
||||
* .toList(); // = [3, 4, 5]
|
||||
* }</pre>
|
||||
* <p>
|
||||
* 与{@code JDK9}中的{@code dropWhile}方法不太一样,此操作为顺序且有状态的中间操作。
|
||||
*
|
||||
* <p>与{@code JDK9}中的{@code dropWhile}方法不太一样,此操作为顺序且有状态的中间操作。
|
||||
* 即使在并行流中,该操作仍然是顺序执行的,并且不影响后续的并行操作:
|
||||
* <pre>{@code
|
||||
* EasyStream.iterate(1, i -> i + 1)
|
||||
@ -251,7 +262,6 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
|
||||
/**
|
||||
* 返回与指定函数将元素作为参数执行后组成的流。操作带下标,并行流时下标永远为-1
|
||||
* 这是一个无状态中间操作
|
||||
*
|
||||
* @param action 指定的函数
|
||||
* @return 返回叠加操作后的FastStream
|
||||
* @apiNote 该方法存在的意义主要是用来调试
|
||||
@ -270,7 +280,7 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
|
||||
if (isParallel()) {
|
||||
return peek(e -> action.accept(e, NOT_FOUND_ELEMENT_INDEX));
|
||||
} 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()));
|
||||
}
|
||||
}
|
||||
@ -309,6 +319,7 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
|
||||
* @param obj 元素
|
||||
* @return 流
|
||||
*/
|
||||
@SuppressWarnings({"SpellCheckingInspection", "unchecked"})
|
||||
default S unshift(final T... obj) {
|
||||
Stream<T> result = unwrap();
|
||||
if (ArrayUtil.isNotEmpty(obj)) {
|
||||
@ -480,9 +491,10 @@ public interface TransformableWrappedStream<T, S extends TransformableWrappedStr
|
||||
Objects.requireNonNull(childrenGetter);
|
||||
Objects.requireNonNull(childrenSetter);
|
||||
final MutableObj<Function<T, EasyStream<T>>> recursiveRef = new MutableObj<>();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Function<T, EasyStream<T>> recursive = e -> EasyStream.of(childrenGetter.apply(e))
|
||||
.flat(recursiveRef.get())
|
||||
.unshift(e);
|
||||
.flat(recursiveRef.get())
|
||||
.unshift(e);
|
||||
recursiveRef.set(recursive);
|
||||
return wrap(flatMap(recursive).peek(e -> childrenSetter.accept(e, null)));
|
||||
}
|
||||
|
@ -269,6 +269,7 @@ public interface WrappedStream<T, S extends WrappedStream<T, S>> extends Stream<
|
||||
@Override
|
||||
default <A> A[] toArray(final IntFunction<A[]> generator) {
|
||||
Objects.requireNonNull(generator);
|
||||
//noinspection SuspiciousToArrayCall
|
||||
return unwrap().toArray(generator);
|
||||
}
|
||||
|
||||
@ -547,7 +548,7 @@ public interface WrappedStream<T, S extends WrappedStream<T, S>> extends Stream<
|
||||
* @return 流
|
||||
*/
|
||||
@Override
|
||||
default S onClose(Runnable closeHandler) {
|
||||
default S onClose(final Runnable closeHandler) {
|
||||
return wrap(unwrap().onClose(closeHandler));
|
||||
}
|
||||
|
||||
|
25
hutool-core/src/test/java/cn/hutool/core/text/dfa/issueI5Q4HDTest.java
Executable file
25
hutool-core/src/test/java/cn/hutool/core/text/dfa/issueI5Q4HDTest.java
Executable 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());
|
||||
}
|
||||
}
|
@ -31,6 +31,8 @@ public class SM2Test {
|
||||
final KeyPair pair = KeyUtil.generateKeyPair("SM2");
|
||||
Assert.assertNotNull(pair.getPrivate());
|
||||
Assert.assertNotNull(pair.getPublic());
|
||||
|
||||
new SM2(pair.getPrivate(), pair.getPublic());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -319,4 +321,9 @@ public class SM2Test {
|
||||
// 04占位一个字节
|
||||
Assert.assertEquals(65, sm2.getQ(false).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void issuesI5PWQ4Test(){
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1022,6 +1022,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
||||
*
|
||||
* @param <T> 结果类型
|
||||
* @param function 响应内容处理函数
|
||||
* @return 结果值
|
||||
* @since 5.8.5
|
||||
*/
|
||||
public <T> T thenFunction(final Function<HttpResponse, T> function) {
|
||||
|
@ -1,7 +1,10 @@
|
||||
package cn.hutool.json;
|
||||
|
||||
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.json.convert.JSONConverter;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.StringWriter;
|
||||
@ -14,7 +17,7 @@ import java.util.function.Predicate;
|
||||
*
|
||||
* @author Looly
|
||||
*/
|
||||
public interface JSON extends Cloneable, Serializable {
|
||||
public interface JSON extends Converter, Cloneable, Serializable {
|
||||
|
||||
/**
|
||||
* 获取JSON配置
|
||||
@ -171,6 +174,11 @@ public interface JSON extends Cloneable, Serializable {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import cn.hutool.json.serialize.JSONWriter;
|
||||
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
@ -231,11 +230,6 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T toBean(final Type type) {
|
||||
return JSON.super.toBean(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据给定名列表,与其位置对应的值组成JSONObject
|
||||
*
|
||||
|
@ -1,10 +1,18 @@
|
||||
package cn.hutool.json;
|
||||
|
||||
import cn.hutool.core.comparator.CompareUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
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.time.temporal.TemporalAccessor;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 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());
|
||||
};
|
||||
|
||||
/**
|
||||
* 创建默认的配置项
|
||||
|
@ -10,7 +10,6 @@ import cn.hutool.json.serialize.JSONWriter;
|
||||
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Collection;
|
||||
@ -150,11 +149,6 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T toBean(final Type type) {
|
||||
return JSON.super.toBean(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定KEY列表的值组成新的JSONArray
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
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.JSONString;
|
||||
|
||||
@ -28,8 +28,9 @@ public class JSONSupport implements JSONString, JSONDeserializer<Object> {
|
||||
*/
|
||||
@Override
|
||||
public Object deserialize(final JSON json) {
|
||||
// TODO 经过两次转换,效率差,待优化
|
||||
BeanUtil.copyProperties(json.toBean(getClass()), this);
|
||||
BeanCopier.of(json,
|
||||
this, this.getClass(),
|
||||
InternalJSONUtil.toCopyOptions(json.getConfig())).copy();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@ public class JSONUtil {
|
||||
* @return JSON
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public static JSON parse(final Object obj, final JSONConfig config) {
|
||||
return JSONConverter.of(config).convert(obj);
|
||||
return JSONConverter.of(config).toJSON(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -1,18 +1,33 @@
|
||||
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.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.reflect.ConstructorUtil;
|
||||
import cn.hutool.core.reflect.TypeReference;
|
||||
import cn.hutool.core.reflect.TypeUtil;
|
||||
import cn.hutool.core.text.StrUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.json.InternalJSONUtil;
|
||||
import cn.hutool.json.JSON;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONConfig;
|
||||
import cn.hutool.json.JSONException;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.hutool.json.serialize.GlobalSerializeMapping;
|
||||
import cn.hutool.json.serialize.JSONDeserializer;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* JSON转换器,实现Object对象转换为{@link JSON},支持的对象:
|
||||
@ -28,6 +43,11 @@ import java.util.Iterator;
|
||||
public class JSONConverter implements Converter {
|
||||
public static final JSONConverter INSTANCE = new JSONConverter(null);
|
||||
|
||||
static {
|
||||
RegisterConverter.getInstance().putCustom(JSONObject.class, INSTANCE);
|
||||
RegisterConverter.getInstance().putCustom(JSONArray.class, INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建JSON转换器
|
||||
*
|
||||
@ -49,6 +69,30 @@ public class JSONConverter implements Converter {
|
||||
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},支持的对象:
|
||||
* <ul>
|
||||
@ -59,17 +103,9 @@ public class JSONConverter implements Converter {
|
||||
*
|
||||
* @param obj 被转换的对象
|
||||
* @return 转换后的对象
|
||||
* @throws ConvertException 转换异常
|
||||
* @throws JSONException 转换异常
|
||||
*/
|
||||
public JSON convert(final Object obj) throws ConvertException {
|
||||
return (JSON) convert(null, obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(final Type targetType, final Object obj) throws ConvertException {
|
||||
if (null == obj) {
|
||||
return null;
|
||||
}
|
||||
public JSON toJSON(final Object obj) throws JSONException {
|
||||
final JSON json;
|
||||
if (obj instanceof JSON) {
|
||||
json = (JSON) obj;
|
||||
@ -87,4 +123,99 @@ public class JSONConverter implements Converter {
|
||||
|
||||
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);
|
||||
}
|
||||
// 特殊类型转换,包括Collection、Map、强转、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
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ import cn.hutool.json.serialize.JSONDeserializer;
|
||||
public class JSONDeserializerConverter extends AbstractConverter {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final JSONDeserializerConverter INSTANCE = new JSONDeserializerConverter();
|
||||
|
||||
@Override
|
||||
protected Object convertInternal(final Class<?> targetClass, final Object value) {
|
||||
// 自定义反序列化
|
||||
|
2
hutool-json/src/test/java/Issue2555Test.java → hutool-json/src/test/java/cn/hutool/json/Issue2555Test.java
Executable file → Normal file
2
hutool-json/src/test/java/Issue2555Test.java → hutool-json/src/test/java/cn/hutool/json/Issue2555Test.java
Executable file → Normal file
@ -1,3 +1,5 @@
|
||||
package cn.hutool.json;
|
||||
|
||||
import cn.hutool.json.JSON;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
@ -472,7 +472,7 @@ public class JSONObjectTest {
|
||||
|
||||
@Test
|
||||
public void setDateFormatTest3() {
|
||||
// 自定义格式为只有秒的时间戳,一版用于JWT
|
||||
// 自定义格式为只有秒的时间戳,一般用于JWT
|
||||
final JSONConfig jsonConfig = JSONConfig.of().setDateFormat("#sss");
|
||||
|
||||
final Date date = DateUtil.parse("2020-06-05 11:16:11");
|
||||
|
18
hutool-poi/src/test/java/cn/hutool/poi/excel/IssueI5Q1TWTest.java
Executable file
18
hutool-poi/src/test/java/cn/hutool/poi/excel/IssueI5Q1TWTest.java
Executable 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));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user