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.initialize();
|
||||
return prop;
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,22 @@ public class PropDesc {
|
||||
* 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>
|
||||
@ -51,6 +67,17 @@ public class PropDesc {
|
||||
this.setter = ClassUtil.setAccessible(setter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在对象的所有属性设置完成后,执行初始化逻辑。
|
||||
* <p>
|
||||
* 预先计算transient关键字和@Transient注解、{@link PropIgnore}注解信息
|
||||
*/
|
||||
public void initialize() {
|
||||
transientForGet = isTransientForGet();
|
||||
transientForSet = isTransientForSet();
|
||||
ignoreGet = isIgnoreGet();
|
||||
ignoreSet = isIgnoreSet();
|
||||
}
|
||||
/**
|
||||
* 获取字段名,如果存在Alias注解,读取注解的值作为名称
|
||||
*
|
||||
@ -137,12 +164,12 @@ public class PropDesc {
|
||||
}
|
||||
|
||||
// 检查transient关键字和@Transient注解
|
||||
if (checkTransient && isTransientForGet()) {
|
||||
if (checkTransient && transientForGet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查@PropIgnore注解
|
||||
return false == isIgnoreGet();
|
||||
return false == ignoreGet;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -207,12 +234,12 @@ public class PropDesc {
|
||||
}
|
||||
|
||||
// 检查transient关键字和@Transient注解
|
||||
if (checkTransient && isTransientForSet()) {
|
||||
if (checkTransient && transientForSet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查@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.LambdaUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
@ -91,6 +92,14 @@ public class CopyOptions implements Serializable {
|
||||
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) {
|
||||
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.collection.CollUtil;
|
||||
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.map.MapBuilder;
|
||||
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
|
||||
public void toMapTest() {
|
||||
// 测试转map的时候返回key
|
||||
|
Loading…
Reference in New Issue
Block a user