mirror of
https://gitee.com/dromara/hutool.git
synced 2025-06-28 13:34:09 +08:00
!1335 优化BeanUtil.copyToList拷贝较大数据量的性能问题
Merge pull request !1335 from IzayoiYurin/v5-dev
This commit is contained in:
commit
3ff79b3f23
@ -181,7 +181,8 @@ public class BeanDesc implements Serializable {
|
|||||||
prop.setter = propIgnoreCase.setter;
|
prop.setter = propIgnoreCase.setter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 所有属性完成填充后的初始化逻辑
|
||||||
|
prop.initialize();
|
||||||
return prop;
|
return prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,22 @@ public class PropDesc {
|
|||||||
* Setter方法
|
* Setter方法
|
||||||
*/
|
*/
|
||||||
protected Method setter;
|
protected Method setter;
|
||||||
|
/**
|
||||||
|
* get方法或字段上有无transient关键字和@Transient注解
|
||||||
|
*/
|
||||||
|
private boolean transientForGet;
|
||||||
|
/**
|
||||||
|
* set方法或字段上有无transient关键字和@Transient注解
|
||||||
|
*/
|
||||||
|
private boolean transientForSet;
|
||||||
|
/**
|
||||||
|
* 检查set方法和字段有无@PropIgnore注解
|
||||||
|
*/
|
||||||
|
private boolean ignoreGet;
|
||||||
|
/**
|
||||||
|
* 检查set方法和字段有无@PropIgnore注解
|
||||||
|
*/
|
||||||
|
private boolean ignoreSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造<br>
|
* 构造<br>
|
||||||
@ -51,6 +67,17 @@ public class PropDesc {
|
|||||||
this.setter = ClassUtil.setAccessible(setter);
|
this.setter = ClassUtil.setAccessible(setter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在对象的所有属性设置完成后,执行初始化逻辑。
|
||||||
|
* <p>
|
||||||
|
* 预先计算transient关键字和@Transient注解、{@link PropIgnore}注解信息
|
||||||
|
*/
|
||||||
|
public void initialize() {
|
||||||
|
transientForGet = isTransientForGet();
|
||||||
|
transientForSet = isTransientForSet();
|
||||||
|
ignoreGet = isIgnoreGet();
|
||||||
|
ignoreSet = isIgnoreSet();
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 获取字段名,如果存在Alias注解,读取注解的值作为名称
|
* 获取字段名,如果存在Alias注解,读取注解的值作为名称
|
||||||
*
|
*
|
||||||
@ -137,12 +164,12 @@ public class PropDesc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检查transient关键字和@Transient注解
|
// 检查transient关键字和@Transient注解
|
||||||
if (checkTransient && isTransientForGet()) {
|
if (checkTransient && transientForGet) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查@PropIgnore注解
|
// 检查@PropIgnore注解
|
||||||
return false == isIgnoreGet();
|
return false == ignoreGet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -207,12 +234,12 @@ public class PropDesc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检查transient关键字和@Transient注解
|
// 检查transient关键字和@Transient注解
|
||||||
if (checkTransient && isTransientForSet()) {
|
if (checkTransient && transientForSet) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查@PropIgnore注解
|
// 检查@PropIgnore注解
|
||||||
return false == isIgnoreSet();
|
return false == ignoreSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,6 +9,7 @@ import cn.hutool.core.lang.Editor;
|
|||||||
import cn.hutool.core.lang.func.Func1;
|
import cn.hutool.core.lang.func.Func1;
|
||||||
import cn.hutool.core.lang.func.LambdaUtil;
|
import cn.hutool.core.lang.func.LambdaUtil;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
|
import cn.hutool.core.util.ClassUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
@ -91,6 +92,14 @@ public class CopyOptions implements Serializable {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 快速处理简单值类型的转换
|
||||||
|
if (type instanceof Class){
|
||||||
|
Class<?> targetType = (Class<?>) type;
|
||||||
|
if (ClassUtil.isSimpleValueType(targetType) && targetType.isInstance(value)) {
|
||||||
|
return targetType.cast(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (value instanceof IJSONTypeConverter) {
|
if (value instanceof IJSONTypeConverter) {
|
||||||
return ((IJSONTypeConverter) value).toBean(ObjectUtil.defaultIfNull(type, Object.class));
|
return ((IJSONTypeConverter) value).toBean(ObjectUtil.defaultIfNull(type, Object.class));
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ import cn.hutool.core.bean.copier.CopyOptions;
|
|||||||
import cn.hutool.core.bean.copier.ValueProvider;
|
import cn.hutool.core.bean.copier.ValueProvider;
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.collection.ListUtil;
|
import cn.hutool.core.collection.ListUtil;
|
||||||
|
import cn.hutool.core.date.StopWatch;
|
||||||
|
import cn.hutool.core.lang.Console;
|
||||||
import cn.hutool.core.lang.Dict;
|
import cn.hutool.core.lang.Dict;
|
||||||
import cn.hutool.core.map.MapBuilder;
|
import cn.hutool.core.map.MapBuilder;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
@ -707,6 +709,37 @@ public class BeanUtilTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void copyLargeListTest(){
|
||||||
|
final SubPerson person = new SubPerson();
|
||||||
|
person.setName("测试A11");
|
||||||
|
person.setAge(14);
|
||||||
|
person.setOpenid("11213232");
|
||||||
|
|
||||||
|
person.setId(UUID.randomUUID());
|
||||||
|
person.setSubName("sub名字");
|
||||||
|
person.setSlow(true);
|
||||||
|
person.setDate(LocalDateTime.now());
|
||||||
|
person.setDate2(LocalDate.now());
|
||||||
|
|
||||||
|
final List<SubPerson> list = new ArrayList<>();
|
||||||
|
CollUtil.padRight(list, 1000, person);
|
||||||
|
|
||||||
|
// 预先构建一次缓存,防止干扰
|
||||||
|
BeanUtil.copyProperties(person, new SubPerson2());
|
||||||
|
// org.springframework.beans.BeanUtils.copyProperties(new SubPerson(), new SubPerson2());
|
||||||
|
|
||||||
|
Console.log("copy bean size: {}\n", list.size());
|
||||||
|
final StopWatch stopWatch = new StopWatch();
|
||||||
|
stopWatch.start("BeanUtil#copyToList");
|
||||||
|
List<SubPerson2> copyList = BeanUtil.copyToList(list, SubPerson2.class);
|
||||||
|
// list.forEach(item -> org.springframework.beans.BeanUtils.copyProperties(item, new SubPerson2()));
|
||||||
|
stopWatch.stop();
|
||||||
|
Console.log(stopWatch.prettyPrint());
|
||||||
|
assertEquals(copyList.size(),list.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void toMapTest() {
|
public void toMapTest() {
|
||||||
// 测试转map的时候返回key
|
// 测试转map的时候返回key
|
||||||
|
Loading…
Reference in New Issue
Block a user