mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
fix code
This commit is contained in:
parent
1176b144d7
commit
c6777244a0
@ -14,9 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.collection;
|
||||
package org.dromara.hutool.core.collection.set;
|
||||
|
||||
import org.dromara.hutool.core.collection.set.SetFromMap;
|
||||
import org.dromara.hutool.core.map.concurrent.SafeConcurrentHashMap;
|
||||
|
||||
import java.util.Collection;
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.collection.set;
|
||||
|
||||
import org.dromara.hutool.core.map.concurrent.ConcurrentLinkedHashMap;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 通过{@link ConcurrentLinkedHashMap}实现的线程安全HashSet
|
||||
*
|
||||
* @param <E> 元素类型
|
||||
* @author Looly
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public class ConcurrentLinkedHashSet<E> extends SetFromMap<E> {
|
||||
private static final long serialVersionUID = 7997886765361607470L;
|
||||
|
||||
// ----------------------------------------------------------------------------------- Constructor start
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*/
|
||||
public ConcurrentLinkedHashSet() {
|
||||
super(new ConcurrentLinkedHashMap.Builder<E, Boolean>().build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造<br>
|
||||
* 触发因子为默认的0.75
|
||||
*
|
||||
* @param initialCapacity 初始大小
|
||||
*/
|
||||
public ConcurrentLinkedHashSet(final int initialCapacity) {
|
||||
super(new ConcurrentLinkedHashMap.Builder<E, Boolean>().initialCapacity(initialCapacity).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param initialCapacity 初始大小
|
||||
* @param concurrencyLevel 线程并发度
|
||||
*/
|
||||
public ConcurrentLinkedHashSet(final int initialCapacity, final int concurrencyLevel) {
|
||||
super(new ConcurrentLinkedHashMap.Builder<E, Boolean>()
|
||||
.initialCapacity(initialCapacity)
|
||||
.concurrencyLevel(concurrencyLevel)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 从已有集合中构造
|
||||
*
|
||||
* @param iter {@link Iterable}
|
||||
*/
|
||||
public ConcurrentLinkedHashSet(final Iterable<E> iter) {
|
||||
super(iter instanceof Collection ?
|
||||
new ConcurrentLinkedHashMap.Builder<E, Boolean>().initialCapacity(((Collection<E>) iter).size()).build() :
|
||||
new ConcurrentLinkedHashMap.Builder<E, Boolean>().build());
|
||||
if (iter instanceof Collection) {
|
||||
this.addAll((Collection<E>) iter);
|
||||
} else {
|
||||
for (final E e : iter) {
|
||||
this.add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----------------------------------------------------------------------------------- Constructor end
|
||||
}
|
@ -154,23 +154,23 @@ public class CompositeConverter extends RegisterConverter {
|
||||
return converter.convert(type, value, defaultValue);
|
||||
}
|
||||
|
||||
Class<T> rowType = (Class<T>) TypeUtil.getClass(type);
|
||||
if (null == rowType) {
|
||||
Class<T> rawType = (Class<T>) TypeUtil.getClass(type);
|
||||
if (null == rawType) {
|
||||
if (null != defaultValue) {
|
||||
rowType = (Class<T>) defaultValue.getClass();
|
||||
rawType = (Class<T>) defaultValue.getClass();
|
||||
} else {
|
||||
throw new ConvertException("Can not get class from type: {}", type);
|
||||
}
|
||||
}
|
||||
|
||||
// 特殊类型转换,包括Collection、Map、强转、Array等
|
||||
final T result = convertSpecial(type, rowType, value, defaultValue);
|
||||
final T result = convertSpecial(type, rawType, value, defaultValue);
|
||||
if (null != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// 尝试转Bean
|
||||
if (BeanUtil.isWritableBean(rowType)) {
|
||||
if (BeanUtil.isWritableBean(rawType)) {
|
||||
return (T) BeanConverter.INSTANCE.convert(type, value);
|
||||
}
|
||||
|
||||
@ -193,80 +193,81 @@ public class CompositeConverter extends RegisterConverter {
|
||||
*
|
||||
* @param <T> 转换的目标类型(转换器转换到的类型)
|
||||
* @param type 类型
|
||||
* @param rawType 原始类型
|
||||
* @param value 值
|
||||
* @param defaultValue 默认值
|
||||
* @return 转换后的值
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T convertSpecial(final Type type, final Class<T> rowType, final Object value, final T defaultValue) {
|
||||
if (null == rowType) {
|
||||
private <T> T convertSpecial(final Type type, final Class<T> rawType, final Object value, final T defaultValue) {
|
||||
if (null == rawType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 日期、java.sql中的日期以及自定义日期统一处理
|
||||
if (Date.class.isAssignableFrom(rowType)) {
|
||||
if (Date.class.isAssignableFrom(rawType)) {
|
||||
return DateConverter.INSTANCE.convert(type, value, defaultValue);
|
||||
}
|
||||
|
||||
// 集合转换(含有泛型参数,不可以默认强转)
|
||||
if (Collection.class.isAssignableFrom(rowType)) {
|
||||
if (Collection.class.isAssignableFrom(rawType)) {
|
||||
return (T) CollectionConverter.INSTANCE.convert(type, value, (Collection<?>) defaultValue);
|
||||
}
|
||||
|
||||
// Map类型(含有泛型参数,不可以默认强转)
|
||||
if (Map.class.isAssignableFrom(rowType)) {
|
||||
if (Map.class.isAssignableFrom(rawType)) {
|
||||
return (T) MapConverter.INSTANCE.convert(type, value, (Map<?, ?>) defaultValue);
|
||||
}
|
||||
|
||||
// issue#I6SZYB Entry类(含有泛型参数,不可以默认强转)
|
||||
if (Map.Entry.class.isAssignableFrom(rowType)) {
|
||||
if (Map.Entry.class.isAssignableFrom(rawType)) {
|
||||
return (T) EntryConverter.INSTANCE.convert(type, value);
|
||||
}
|
||||
|
||||
// 默认强转
|
||||
if (rowType.isInstance(value)) {
|
||||
if (rawType.isInstance(value)) {
|
||||
return (T) value;
|
||||
}
|
||||
|
||||
// 原始类型转换
|
||||
if (rowType.isPrimitive()) {
|
||||
if (rawType.isPrimitive()) {
|
||||
return PrimitiveConverter.INSTANCE.convert(type, value, defaultValue);
|
||||
}
|
||||
|
||||
// 数字类型转换
|
||||
if (Number.class.isAssignableFrom(rowType)) {
|
||||
if (Number.class.isAssignableFrom(rawType)) {
|
||||
return NumberConverter.INSTANCE.convert(type, value, defaultValue);
|
||||
}
|
||||
|
||||
// 枚举转换
|
||||
if (rowType.isEnum()) {
|
||||
if (rawType.isEnum()) {
|
||||
return EnumConverter.INSTANCE.convert(type, value, defaultValue);
|
||||
}
|
||||
|
||||
// 数组转换
|
||||
if (rowType.isArray()) {
|
||||
if (rawType.isArray()) {
|
||||
return ArrayConverter.INSTANCE.convert(type, value, defaultValue);
|
||||
}
|
||||
|
||||
// Record
|
||||
if (RecordUtil.isRecord(rowType)) {
|
||||
if (RecordUtil.isRecord(rawType)) {
|
||||
return (T) RecordConverter.INSTANCE.convert(type, value);
|
||||
}
|
||||
|
||||
// Kotlin Bean
|
||||
if (KClassUtil.isKotlinClass(rowType)) {
|
||||
if (KClassUtil.isKotlinClass(rawType)) {
|
||||
return (T) KBeanConverter.INSTANCE.convert(type, value);
|
||||
}
|
||||
|
||||
// issue#I7FQ29 Class
|
||||
if ("java.lang.Class".equals(rowType.getName())) {
|
||||
if ("java.lang.Class".equals(rawType.getName())) {
|
||||
return (T) ClassConverter.INSTANCE.convert(type, value);
|
||||
}
|
||||
|
||||
// 空值转空Bean
|
||||
if (ObjUtil.isEmpty(value)) {
|
||||
// issue#3649 空值转空对象,则直接实例化
|
||||
return ConstructorUtil.newInstanceIfPossible(rowType);
|
||||
return ConstructorUtil.newInstanceIfPossible(rawType);
|
||||
}
|
||||
|
||||
// 表示非需要特殊转换的对象
|
||||
|
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.convert;
|
||||
|
||||
import org.dromara.hutool.core.collection.set.ConcurrentHashSet;
|
||||
import org.dromara.hutool.core.stream.StreamUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 用户自定义转换器<br>
|
||||
* 通过自定义实现{@link PredicateConverter},可以通过{@link PredicateConverter#test(Object)} 检查目标类型是否匹配<br>
|
||||
* 如果匹配,则直接转换,否则使用默认转换器转换。
|
||||
*
|
||||
* @author Looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class CustomConverter implements Converter, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载
|
||||
*/
|
||||
private static class SingletonHolder {
|
||||
/**
|
||||
* 静态初始化器,由JVM来保证线程安全
|
||||
*/
|
||||
private static final RegisterConverter INSTANCE = new RegisterConverter();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得单例的 RegisterConverter
|
||||
*
|
||||
* @return RegisterConverter
|
||||
*/
|
||||
public static RegisterConverter getInstance() {
|
||||
return CustomConverter.SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户自定义类型转换器
|
||||
*/
|
||||
private volatile Set<PredicateConverter> converterSet;
|
||||
|
||||
@Override
|
||||
public Object convert(final Type targetType, final Object value) throws ConvertException {
|
||||
final Converter customConverter = getCustomConverter(targetType);
|
||||
return null == customConverter ? null : customConverter.convert(targetType, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得匹配类型的自定义转换器
|
||||
*
|
||||
* @param type 类型
|
||||
* @return 转换器
|
||||
*/
|
||||
public Converter getCustomConverter(final Type type) {
|
||||
return getConverterFromSet(this.converterSet, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 登记自定义转换器
|
||||
*
|
||||
* @param converter 转换器
|
||||
* @return ConverterRegistry
|
||||
*/
|
||||
public CustomConverter add(final PredicateConverter converter) {
|
||||
if (null == this.converterSet) {
|
||||
synchronized (this) {
|
||||
if (null == this.converterSet) {
|
||||
this.converterSet = new ConcurrentHashSet<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
this.converterSet.add(converter);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从指定集合中查找满足条件的转换器
|
||||
*
|
||||
* @param type 类型
|
||||
* @return 转换器
|
||||
*/
|
||||
private static Converter getConverterFromSet(final Set<? extends PredicateConverter> converterSet, final Type type) {
|
||||
return StreamUtil.of(converterSet).filter((predicate) -> predicate.test(type)).findFirst().orElse(null);
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.convert;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* 断言转换器<br>
|
||||
* 判断目标对象是否满足断言,满足则转换,否则跳过<br>
|
||||
* 实现此接口同样可以不判断断言而直接转换
|
||||
*
|
||||
* @author Looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public interface PredicateConverter extends Converter, Predicate<Type> {
|
||||
}
|
@ -42,7 +42,10 @@ import java.util.concurrent.atomic.AtomicLongArray;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* 基于类型注册的转换器,转换器默认提供一些固定的类型转换,用户可调用{@link #putCustom(Type, Converter)} 注册自定义转换规则
|
||||
* 基于类型注册的转换器<br>
|
||||
* 即转换的目标类型和转换器一一对应,转换器只针对目标类型,不针对源类型<br>
|
||||
* 转换器默认提供一些固定的类型转换,用户可调用{@link #putCustom(Type, Converter)} 注册自定义转换规则<br>
|
||||
* 注意:注册的转换器要求目标类型必须一致,不能是子类等
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
@ -164,7 +167,7 @@ public class RegisterConverter implements Converter, Serializable {
|
||||
* 注册默认转换器
|
||||
*/
|
||||
private void registerDefault() {
|
||||
defaultConverterMap = new SafeConcurrentHashMap<>(64);
|
||||
final Map<Class<?>, Converter> defaultConverterMap = new SafeConcurrentHashMap<>(64);
|
||||
|
||||
// 包装类转换器
|
||||
defaultConverterMap.put(Character.class, new CharacterConverter());
|
||||
@ -220,5 +223,7 @@ public class RegisterConverter implements Converter, Serializable {
|
||||
defaultConverterMap.put(Pair.class, PairConverter.INSTANCE);// since 6.0.0
|
||||
defaultConverterMap.put(Triple.class, TripleConverter.INSTANCE);// since 6.0.0
|
||||
defaultConverterMap.put(Tuple.class, TupleConverter.INSTANCE);// since 6.0.0
|
||||
|
||||
this.defaultConverterMap = defaultConverterMap;
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package org.dromara.hutool.core.io.watch.watchers;
|
||||
|
||||
import org.dromara.hutool.core.collection.ConcurrentHashSet;
|
||||
import org.dromara.hutool.core.collection.set.ConcurrentHashSet;
|
||||
import org.dromara.hutool.core.io.watch.Watcher;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.thread.ThreadUtil;
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package org.dromara.hutool.core.stream;
|
||||
|
||||
import org.dromara.hutool.core.collection.ConcurrentHashSet;
|
||||
import org.dromara.hutool.core.collection.set.ConcurrentHashSet;
|
||||
import org.dromara.hutool.core.collection.iter.IterUtil;
|
||||
import org.dromara.hutool.core.map.multi.RowKeyTable;
|
||||
import org.dromara.hutool.core.map.multi.Table;
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
package org.dromara.hutool.core.data.id;
|
||||
|
||||
import org.dromara.hutool.core.collection.ConcurrentHashSet;
|
||||
import org.dromara.hutool.core.collection.set.ConcurrentHashSet;
|
||||
import org.dromara.hutool.core.exception.HutoolException;
|
||||
import org.dromara.hutool.core.lang.Console;
|
||||
import org.dromara.hutool.core.lang.tuple.Pair;
|
||||
|
@ -12,8 +12,7 @@
|
||||
|
||||
package org.dromara.hutool.core.data.id;
|
||||
|
||||
import org.dromara.hutool.core.collection.ConcurrentHashSet;
|
||||
import org.dromara.hutool.core.lang.Console;
|
||||
import org.dromara.hutool.core.collection.set.ConcurrentHashSet;
|
||||
import org.dromara.hutool.core.thread.ThreadUtil;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
package org.dromara.hutool.core.util;
|
||||
|
||||
import org.dromara.hutool.core.collection.ConcurrentHashSet;
|
||||
import org.dromara.hutool.core.collection.set.ConcurrentHashSet;
|
||||
import org.dromara.hutool.core.date.DateUtil;
|
||||
import org.dromara.hutool.core.date.StopWatch;
|
||||
import org.dromara.hutool.core.exception.HutoolException;
|
||||
|
@ -20,7 +20,6 @@ import org.dromara.hutool.core.bean.path.BeanPath;
|
||||
import org.dromara.hutool.core.convert.ConvertException;
|
||||
import org.dromara.hutool.core.convert.Converter;
|
||||
import org.dromara.hutool.core.lang.mutable.MutableEntry;
|
||||
import org.dromara.hutool.json.convert.JSONConverter;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.StringWriter;
|
||||
@ -193,6 +192,6 @@ public interface JSON extends Converter, Cloneable, Serializable {
|
||||
|
||||
@Override
|
||||
default Object convert(final Type targetType, final Object value) throws ConvertException {
|
||||
return JSONConverter.of(config()).convert(targetType, value);
|
||||
return config().getConverter().convert(targetType, value);
|
||||
}
|
||||
}
|
||||
|
@ -61,8 +61,9 @@ public class JSONConverter implements Converter, Serializable {
|
||||
public static final JSONConverter INSTANCE = new JSONConverter(null);
|
||||
|
||||
static {
|
||||
RegisterConverter.getInstance().putCustom(JSONObject.class, INSTANCE);
|
||||
RegisterConverter.getInstance().putCustom(JSONArray.class, INSTANCE);
|
||||
final RegisterConverter converter = RegisterConverter.getInstance();
|
||||
converter.putCustom(JSONObject.class, INSTANCE);
|
||||
converter.putCustom(JSONArray.class, INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user