Chao's Blog Chao's Blog
首页
  • vue

    • vue路由
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • java
  • spring
  • springboot
  • springcloud
  • git
  • maven
  • nginx
  • tomcat
  • springmvc
  • jvm
  • 图数据库
  • mysql数据库
  • redis数据库
  • windows下docker安装nginx并挂载目录
  • linux命令
  • linux安装软件
  • linux脚本
  • idea
  • vscode
  • 归档
  • 综合项目

    • 若依项目
    • mall项目
  • java
  • mybatis
  • xxl-job
  • mybatis
GitHub (opens new window)

~chao

永远菜鸟,不断努力~
首页
  • vue

    • vue路由
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • java
  • spring
  • springboot
  • springcloud
  • git
  • maven
  • nginx
  • tomcat
  • springmvc
  • jvm
  • 图数据库
  • mysql数据库
  • redis数据库
  • windows下docker安装nginx并挂载目录
  • linux命令
  • linux安装软件
  • linux脚本
  • idea
  • vscode
  • 归档
  • 综合项目

    • 若依项目
    • mall项目
  • java
  • mybatis
  • xxl-job
  • mybatis
GitHub (opens new window)
  • java

    • java深度克隆
    • restemplate

    • hashcode()和equals()的作用、区别、联系
    • java8新特性
    • 接口与抽象类
    • java深度克隆工具类支持对象和list克隆
      • 子线程执行10次后,主线程再运行5次,这样交替执行三遍
      • CountDownLatch的理解和使用
      • CAS详解
      • java中的各种锁详细介绍
      • java线程池
      • Java锁之偏向级锁、轻量级锁、重量级锁
      • Transactional注解与try{}catch(Exception e){}同时使用事务控制无效问题
      • JAVA8 optional用法
      • CyclicBarrier 使用详解
      • Semaphore 使用及原理
      • Java中七大垃圾回收器
    • spring

    • springboot

    • springcloud

    • git

    • maven

    • nginx

    • tomcat

    • springmvc

    • jvm

    • 正则表达式

    • 消息中间件

    • python

    • 后端
    • java
    ~chao
    2023-02-09
    目录

    java深度克隆工具类支持对象和list克隆

    # 第一步:创建工具类

    转载自:java深度克隆工具类 - 简书 (jianshu.com) (opens new window)

    直接使用commons-beanutils实现对象拷贝,引入pom

    <dependency>    
       <groupId>commons-beanutils</groupId> 
      <artifactId>commons-beanutils</artifactId>    
      <version>1.9.3</version>
    </dependency>
    
    1
    2
    3
    4
    5

    创建工具类:BeanUtils

      public class BeanUtils {
            /**
             * @param orig  源对象
             * @param dest  目标对象
             */
            public static void copyProperties(final Object orig,final Object dest){
                try{
                    org.apache.commons.beanutils.BeanUtils.copyProperties(dest, orig);
                }catch (Exception e){
                    throw new RuntimeException(e.getMessage());
                }
            }
    
            /**
             * @Description:拷贝list元素对象,将origs中的元素信息,拷贝覆盖至dests中
             * @param origs 源list对象
             * @param dests 目标list对象
             * @param origsElementTpe 源list元素类型对象
             * @param destElementTpe 目标list元素类型对象
             * @param <T1> 源list元素类型
             * @param <T2> 目标list元素类型
             */
            public static <T1,T2> void copyProperties(final List<T1> origs, final List<T2> dests, Class<T1> origsElementTpe, Class<T2> destElementTpe){
                if(origs==null||dests==null){
                    return ;
                }
                if(dests.size()!=0){
                    //防止目标对象被覆盖,要求必须长度为零
                    throw new RuntimeException("目标对象存在值");
                }
                try{
                    for (T1 orig: origs) {
                        T2 t = destElementTpe.newInstance();
                        dests.add(t);
                        copyProperties(orig,t);
                    }
                }catch (Exception e){
                    throw new RuntimeException(e.getMessage());
                }
            }
        }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42

    注:抛出异常部分可根据实际项目需要,抛出自定义异常。

    # 第二步:测试

    创建两个实体类,实体类只相差一个属性,用于测试

    BeanOne.java

    private String id;
    private String name;
    private String beanOne;
    
    1
    2
    3

    BeanTwo.java

    private String id;
    private String name;
    private String beanTwo;
    
    1
    2
    3
    • 测试直接拷贝对象:
    BeanOne orig = new BeanOne("123","张三","one");//直接赋值
    BeanOne dest = orig;//修改值
    dest.setId("456");
    dest.setName("李四");
    System.out.println("赋值后的原始值:"+orig.toString());
    System.out.println("赋值后新对象值:"+dest.toString());
    
    1
    2
    3
    4
    5
    6

    image

    结果:直接拷贝对象时,是地址拷贝,orig与dest指向同一个地址,导致修改dest会影响到orig

    • 测试深度克隆拷贝相同类型对象:
    BeanOne orig = new BeanOne("123","张三","one");//深度克隆
    BeanOne dest = new BeanOne();
    BeanUtils.copyProperties(orig,dest);
    dest.setId("456");
    dest.setName("李四");
    System.out.println("赋值后的原始值:"+orig.toString());
    System.out.println("赋值后新对象值:"+dest.toString());
    
    1
    2
    3
    4
    5
    6
    7

    image

    结果:修改dest不会影响到orig的值

    • 测试深度克隆拷贝不相同类型对象:
    BeanOne orig = new BeanOne("123","张三","one");//深度克隆
    BeanTwo dest = new BeanTwo();
    BeanUtils.copyProperties(orig,dest);
    dest.setName("李四");
    System.out.println("赋值后的原始值:"+orig.toString());
    System.out.println("赋值后新对象值:"+dest.toString());
    
    1
    2
    3
    4
    5
    6

    image

    结果:不同类型的对象之间的拷贝,则相同属性会拷贝,不同属性不会拷贝

    注:追溯org.apache.commons.beanutils.BeanUtils源码,克制对象之间的拷贝是通过属性名的而与类型无关,未避免异常,两个不同类型的对象之间的拷贝,尽可能保证相同属性名的类型也保持一致。

    • 测试深度克隆拷贝集合对象:
    List<BeanOne> origs = new ArrayList<>();
    origs.add(new BeanOne("123","张三","one"));
    origs.add(new BeanOne("456","李四","one1"));//深度克隆
    List<BeanTwo> dests = new ArrayList<>();
    BeanUtils.copyProperties(origs,dests,BeanOne.class,BeanTwo.class);
    for(BeanTwo temp : dests){    
        temp.setName("都是two");
    }
    System.out.println("赋值后的原始值:"+origs.toString());
    System.out.println("赋值后新对象值:"+dests.toString());
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    image

    结果:拷贝成功,且不影响原始值

    0人点赞

    工具类 (opens new window)

    编辑 (opens new window)
    上次更新: 2024/01/26, 05:03:22
    接口与抽象类
    子线程执行10次后,主线程再运行5次,这样交替执行三遍

    ← 接口与抽象类 子线程执行10次后,主线程再运行5次,这样交替执行三遍→

    最近更新
    01
    python使用生成器读取大文件-500g
    09-24
    02
    Windows环境下 Docker Desktop 安装 Nginx
    04-10
    03
    使用nginx部署多个前端项目(三种方式)
    04-10
    更多文章>
    Theme by Vdoing | Copyright © 2022-2024 chaos | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式