java如何拷贝复制对象和集合问题

 更新时间:2023年09月27日 08:39:45   作者:Yang疯狂打码中  
这篇文章主要介绍了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方法返回值改变

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot中项目结构的项目实践

    SpringBoot中项目结构的项目实践

    SpringBoot项目结构遵循Maven或Gradle的标准目录结构,融入了SpringBoot的特定约定,本文就来介绍一下SpringBoot中项目结构的项目,感兴趣的可以了解一下
    2025-03-03
  • springSecurity+jwt使用小结

    springSecurity+jwt使用小结

    本文介绍了使用Spring Security与JWT进行身份验证和授权,实现用户认证和授权的详细流程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-11-11
  • 初学者Android studio安装图文详解

    初学者Android studio安装图文详解

    本文给大家分享android studio 安装图文详解包括下载安装及遇到的问题,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-09-09
  • IDEA配置Java类方法注释模板实践

    IDEA配置Java类方法注释模板实践

    这篇文章主要介绍了IDEA配置Java类方法注释模板实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2026-03-03
  • Java 结构化并发Structured Concurrency实践举例

    Java 结构化并发Structured Concurrency实践举例

    Java21结构化并发通过作用域和任务句柄统一管理并发生命周期,解决线程泄漏与任务追踪问题,提升代码安全性和可观测性,其核心目标为资源整合、依赖管理、异常控制,适用于复杂并发场景,未来将与JVM集成并扩展框架支持,本文给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2025-09-09
  • Spring中@RestController注解的使用实现

    Spring中@RestController注解的使用实现

    @RestController是SpringMVC中用于构建RESTful Web服务的核心注解,结合@Controller和@ResponseBody功能,自动将方法返回值序列化为JSON/XML,感兴趣的可以了解一下
    2025-08-08
  • Javaweb动态开发最重要的Servlet详解

    Javaweb动态开发最重要的Servlet详解

    动态web的核心是Servlet,由tomcat解析并执行,本质是Java中的一个类(面向对象)这个类的功能十分强大几乎可以完成全部功能,在Java规范中只有Servlet实现类实例化的对象才能被浏览器访问,所以掌握Servlet具有重要意义
    2022-08-08
  • Java中的xxl-job调度器线程池工作机制

    Java中的xxl-job调度器线程池工作机制

    xxl-job通过快慢线程池分离短时与长时任务,动态降级超时任务至慢池,结合异步触发和资源隔离机制,提升高频调度的性能与稳定性,支撑高并发场景下的可靠任务执行,本文给大家介绍Java: xxl-job调度器线程池工作机制,感兴趣的朋友一起看看吧
    2025-07-07
  • Redis缓存及热点key问题解决方案

    Redis缓存及热点key问题解决方案

    这篇文章主要介绍了Redis缓存及热点key问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • 基于SpringBoot实现一个安全可靠的滑块拼图验证系统

    基于SpringBoot实现一个安全可靠的滑块拼图验证系统

    滑块拼图验证是一种行为验证技术,通过要求用户将拼图块拖动到正确位置来区分人类用户和自动化程序,本文给大家介绍了基于SpringBoot实现滑块拼图验证的完整代码,需要的朋友可以参考下
    2026-03-03

最新评论