java如何拷贝复制对象和集合问题
在Java中常见的对象拷贝方式是使用cglib,Cglib的性能是目前公认最好的,用于解决Bean拷贝的性能问题
下面是以cglib封装的工具类实现对象和集合的拷贝
一、引入依赖
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> <scope>compile</scope> </dependency>
二、创建CglibUtil工具类
其中包含对象和集合的拷贝,还封装了Bean转Map的方法
import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ReflectUtil; import net.sf.cglib.beans.BeanCopier; import net.sf.cglib.beans.BeanMap; import net.sf.cglib.core.Converter; import java.util.Collection; import java.util.List; import java.util.function.BiConsumer; import java.util.function.Supplier; import java.util.stream.Collectors; /** * @author YangBoss * @title: CglibUtil * @projectName frontop-ao * @description: CglibUtil工具类 * @date 2022/6/2 10:18 */ public class CglibUtil { /** * 拷贝Bean对象属性到目标类型<br> * 此方法通过指定目标类型自动创建之,然后拷贝属性 * * @param <T> 目标对象类型 * @param source 源bean对象 * @param targetClass 目标bean类,自动实例化此对象 * @return 目标对象 */ public static <T> T copy(Object source, Class<T> targetClass) { return copy(source, targetClass, null); } /** * 拷贝Bean对象属性<br> * 此方法通过指定目标类型自动创建之,然后拷贝属性 * * @param <T> 目标对象类型 * @param source 源bean对象 * @param targetClass 目标bean类,自动实例化此对象 * @param converter 转换器,无需可传{@code null} * @return 目标对象 */ public static <T> T copy(Object source, Class<T> targetClass, Converter converter) { final T target = ReflectUtil.newInstanceIfPossible(targetClass); copy(source, target, converter); return target; } /** * 拷贝Bean对象属性 * * @param source 源bean对象 * @param target 目标bean对象 */ public static void copy(Object source, Object target) { copy(source, target, null); } /** * 拷贝Bean对象属性 * * @param source 源bean对象 * @param target 目标beBeanCopierCachean对象 * @param converter 转换器,无需可传{@code null} */ public static void copy(Object source, Object target, Converter converter) { Assert.notNull(source, "Source bean must be not null."); Assert.notNull(target, "Target bean must be not null."); final Class<?> sourceClass = source.getClass(); final Class<?> targetClass = target.getClass(); boolean conIsNull = converter == null ? false : true; final BeanCopier beanCopier = BeanCopier.create(sourceClass, targetClass, conIsNull); beanCopier.copy(source, target, converter); } /** * 拷贝List Bean对象属性 * * @param <S> 源bean类型 * @param <T> 目标bean类型 * @param source 源bean对象list * @param target 目标bean对象 * @return 目标bean对象list */ public static <S, T> List<T> copyList(Collection<S> source, Supplier<T> target) { return copyList(source, target, null, null); } /** * 拷贝List Bean对象属性 * * @param source 源bean对象list * @param target 目标bean对象 * @param converter 转换器,无需可传{@code null} * @param <S> 源bean类型 * @param <T> 目标bean类型 * @return 目标bean对象list * @since 5.4.1 */ public static <S, T> List<T> copyList(Collection<S> source, Supplier<T> target, Converter converter) { return copyList(source, target, converter, null); } /** * 拷贝List Bean对象属性 * * @param source 源bean对象list * @param target 目标bean对象 * @param callback 回调对象 * @param <S> 源bean类型 * @param <T> 目标bean类型 * @return 目标bean对象list * @since 5.4.1 */ public static <S, T> List<T> copyList(Collection<S> source, Supplier<T> target, BiConsumer<S, T> callback) { return copyList(source, target, null, callback); } /** * 拷贝List Bean对象属性 * * @param source 源bean对象list * @param target 目标bean对象 * @param converter 转换器,无需可传{@code null} * @param callback 回调对象 * @param <S> 源bean类型 * @param <T> 目标bean类型 * @return 目标bean对象list */ public static <S, T> List<T> copyList(Collection<S> source, Supplier<T> target, Converter converter, BiConsumer<S, T> callback) { return source.stream().map(s -> { T t = target.get(); copy(s, t, converter); if (callback != null) { callback.accept(s, t); } return t; }).collect(Collectors.toList()); } /** * 将Bean转换为Map * * @param bean Bean对象 * @return {@link BeanMap} * @since 5.4.1 */ public static BeanMap toMap(Object bean) { return BeanMap.create(bean); } }
三、测试拷贝对象和集合
拷贝对象测试,再将拷贝的对象和源对象放入集合中对拷贝集合测试
public static void main(String[] args) { /** * 拷贝对象 */ //创建对象 TUser tUser = new TUser(); tUser.setName("李四"); //拷贝对象 TUser tUser2 = CglibUtil.copy(tUser,TUser.class); //打印结果 System.out.println(tUser2.getName()); /** * 拷贝集合 */ //创建集合 List<TUser> list1 = new ArrayList<>(); list1.add(tUser); list1.add(tUser2); //拷贝集合 List<TUser> list2 = CglibUtil.copyList(list1,TUser::new); //打印结果 System.out.println(JSONObject.toJSONString(list2)); }
结果打印
四、注意点
CglibUtil.copy拷贝对象的时候,目标对象被lombok注解@Accessors(chain = true)修饰报空指针
在拷贝对象上不可用注解 @Accessors ,反射获取不到对应的setter,因为这个链式生成的代码带了返回值,此注解会将set方法返回值改变
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
JavaWeb Listener 利用Session统计在线人数
这篇文章主要为大家介绍了JavaWeb Listener 利用Session统计在线人数,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2022-09-09Java高性能实体类转换工具MapStruct的使用教程详解
MapStruct 是一个代码生成器,它基于约定优于配置的方法,极大地简化了 Java bean 类型之间的映射实现,本文主要介绍了MapStruct的具体使用以及如何进行实体类转换,感兴趣的可以了解下2024-03-03Java中的CopyOnWriteArrayList你了解吗
CopyOnWriteArrayList是Java集合框架中的一种线程安全的List实现,这篇文章主要来和大家聊聊CopyOnWriteArrayList的简单使用,需要的可以参考一下2023-06-06java 使用HttpURLConnection发送数据简单实例
这篇文章主要介绍了java 使用HttpURLConnection发送数据简单实例的相关资料,需要的朋友可以参考下2017-06-06Java 枚举类和自定义枚举类和enum声明及实现接口的操作
这篇文章主要介绍了Java 枚举类和自定义枚举类和enum声明及实现接口的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2021-02-02
最新评论