Java 对象复制 Java对象复制6种情况 效率对比 BeanUtils 对象复制 Dozer 复习复制 MapStruct对象复制

本文对比了Java中6种对象复制工具的效率,包括SpringBeanUtils、ApacheBeanUtils、Dozer、HutoolBeanUtil、cglibBeanCopier和MapStruct。测试结果显示,MapStruct的复制效率最高,仅耗时30ms,而Dozer的效率最低。其他工具的效率介于两者之间,MapStruct和cglibBeanCopier表现优秀。ApacheBeanUtils和SpringBeanUtils的效率相近但较低。文章建议在实际项目中考虑使用MapStruct以提高性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        Java 对象复制 Java对象复制6种情况 效率对比 BeanUtils 对象复制 Dozer 复习复制 MapStruct对象复制

一、概述

        在Java开发中,经常会遇到对象的复制转换操作,各种xxAO , 转换到 xxBO , 这就涉及到对象之间的复制。 例如:把 Pig 对象复制到 PigDTO 对象中 ...

        

        在Java中,目前据我所知可以做到对象复制的相关工具有以下 6 种:

1、Spring BeanUtils
2、Apache BeanUtils
3、Dozer
4、Hutool BeanUtil
5、cglib BeanCopier 
6、MapStruct

        

        本文将对比这6中对象复制的效率情况。

二、准备工作

        1、Apache BeanUtils 依赖

<dependency>
  <groupId>commons-beanutils</groupId>
  <artifactId>commons-beanutils</artifactId>
  <version>1.9.1</version>
</dependency>

        2、Dozer 依赖

<dependency>
   <groupId>net.sf.dozer</groupId>
   <artifactId>dozer</artifactId>
   <version>5.5.1</version>
</dependency>

        3、Hutool 依赖

<dependency>
   <groupId>cn.hutool</groupId>
   <artifactId>hutool-all</artifactId>
   <version>5.7.18</version>
</dependency>

        

        4、cglib BeanCopier 依赖

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>5.1.4.RELEASE</version>
</dependency>

-- 或使用 cglib 依赖
<dependency>
   <groupId>cglib</groupId>
   <artifactId>cglib</artifactId>
   <version>3.3.0</version>
</dependency>

        5、MapStructs 依赖

<dependency>
   <groupId>org.mapstruct</groupId>
   <artifactId>mapstruct-jdk8</artifactId>
   <version>1.3.0.Final</version>
</dependency>

<dependency>
   <groupId>org.mapstruct</groupId>
   <artifactId>mapstruct-processor</artifactId>
   <version>1.3.0.Final</version>
</dependency>

        6、Java Bean Pig 和 PigDTO

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Pig {

    private int id ;
    private String name ;
    private List<String> list ;
}

@NoArgsConstructor
@AllArgsConstructor
@Data
public class PigDTO {

    private int id ;
    private String name ;
    private List<String> list ;

}

三、效率对比

        1、springBeanUtils 复制

public void springBeanUtils(Pig a ,PigDTO b){
    org.springframework.beans.BeanUtils.copyProperties(a,b);
}

        2、apacheBeanUtils 复制

public void apacheBeanUtils(Pig a ,PigDTO b) throws InvocationTargetException, IllegalAccessException {
    org.apache.commons.beanutils.BeanUtils.copyProperties(b,a);
}

        3、dozer 复制

public static class DozerUtil{
    static Mapper MAPPER = new DozerBeanMapper();

    /**
     * Description: 普通对象转换
     * @param src
     * @param dest
     * @return T
     * @version v1.0
     * @author wu
     * @date 2023/4/18 14:09
     */
     public static <T>T map(Object src , Class<T> dest){
         if(Objects.isNull(src)){
             return null;
         }
         return MAPPER.map(src,dest);
     }
 }

        4、hutoolBeanUtil 复制

public void hutoolBeanUtil(Pig a ,PigDTO b){
    BeanUtil.copyProperties(a,b);
}

        5、cglibBeanCopier 复制

public void cglibBeanCopier(Pig a ,PigDTO b){
    final BeanCopier beanCopier = BeanCopier.create(a.getClass(), b.getClass(),false);
    beanCopier.copy(a,b,null);
}

        6、mapStrctCopyObj 复制

import com.runcode.springboottourist.beanutil.bean.Pig;
import com.runcode.springboottourist.beanutil.bean.PigDTO;
import org.mapstruct.Mapper;

@Mapper
public interface MapStrctMapping {

    PigDTO pigToPigDTO(Pig pig);
    PigDTO pigToPigDTO2(Pig pig);
}


// 复制代码

public PigDTO mapStrctCopyObj(Pig pig ){
    final MapStrctMapping mapper = Mappers.getMapper(MapStrctMapping.class);
    final PigDTO pigDTO = mapper.pigToPigDTO(pig);
    return pigDTO;
}

        7、复制效率测试

final Pig pig = new Pig(11, "二狗子", Lists.newArrayList("aaa", "bbb", "ccc"));


@Test
public void springBeanUtilsBatchTest() throws Exception{
    int count = 1000 ;
    StopWatch stopWatch = StopWatch.createStarted();
    System.out.println("springBeanUtils 复制 ,"+count +" 次数据,开始====");
    for (int i = 0; i < count; i++) {
        final PigDTO pigDTO = new PigDTO();
        springBeanUtils(pig,pigDTO);
    }
    stopWatch.stop();
    System.out.println("springBeanUtils 复制 ,"+count +" 次数据,结束, 耗时:"+ stopWatch.getTime()+" , 毫秒");
}

@Test
public void apacheBeanUtilsBatchTest() throws Exception {
    int count = 1000;
    StopWatch stopWatch = StopWatch.createStarted();
    System.out.println("apacheBeanUtilsBatchTest 复制 ," + count + " 次数据,开始====");
    for (int i = 0; i < count; i++) {
        final PigDTO pigDTO = new PigDTO();
        apacheBeanUtils(pig,pigDTO);
    }
    stopWatch.stop();
    System.out.println("apacheBeanUtilsBatchTest 复制 ," + count + " 次数据,结束, 耗时:" + stopWatch.getTime() + " , 毫秒");
}

@Test
public void dozerBatchTest() throws Exception{
    int count = 1000;
    StopWatch stopWatch = StopWatch.createStarted();
    System.out.println("dozerBatchTest 复制 ," + count + " 次数据,开始====");
    for (int i = 0; i < count; i++) {
        final PigDTO dozer = dozer(pig, PigDTO.class);
    }
    stopWatch.stop();
    System.out.println("dozerBatchTest 复制 ," + count + " 次数据,结束, 耗时:" + stopWatch.getTime() + " , 毫秒");

}

@Test
public void hutoolBeanUtilBatchTest() throws Exception{
    int count = 1000;
    StopWatch stopWatch = StopWatch.createStarted();
    System.out.println("hutoolBeanUtilBatchTest 复制 ," + count + " 次数据,开始====");
    for (int i = 0; i < count; i++) {
        final PigDTO pigDTO = new PigDTO();
        hutoolBeanUtil(pig,pigDTO);
    }
    stopWatch.stop();
    System.out.println("hutoolBeanUtilBatchTest 复制 ," + count + " 次数据,结束, 耗时:" + stopWatch.getTime() + " , 毫秒");

}

@Test
public void cglibBeanCopierBatchTest() throws Exception{
    int count = 1000;
    StopWatch stopWatch = StopWatch.createStarted();
    System.out.println("cglibBeanCopierBatchTest 复制 ," + count + " 次数据,开始====");
    for (int i = 0; i < count; i++) {
        final PigDTO pigDTO = new PigDTO();
        cglibBeanCopier(pig,pigDTO);
    }
    stopWatch.stop();
    System.out.println("cglibBeanCopierBatchTest 复制 ," + count + " 次数据,结束, 耗时:" + stopWatch.getTime() + " , 毫秒");
}

@Test
public void mapStrctCopyObjBatchTest() throws Exception{
    int count = 1000;
    StopWatch stopWatch = StopWatch.createStarted();
    System.out.println("mapStrctCopyObjBatchTest 复制 ," + count + " 次数据,开始====");
    for (int i = 0; i < count; i++) {
        final PigDTO pigDTO = new PigDTO();
        final PigDTO pigDTO1 = mapStrctCopyObj(pig);
    }
    stopWatch.stop();
    System.out.println("mapStrctCopyObjBatchTest 复制 ," + count + " 次数据,结束, 耗时:" + stopWatch.getTime() + " , 毫秒");
}

        8、结果如下:

1. Spring BeanUtils 耗时:361 ms
2. Apache BeanUtils 耗时: 389 ms
3. Dozer 耗时: 536 ms
4. Hutool BeanUtil 耗时: 261 ms
5. cglib BeanCopier 耗时: 155 ms
6. MapStruct 耗时:30 ms

四、总结

        1、复制效率情况如下:

MapStruct > cglib BeanCopier > Hutool BeanUtil > Spring BeanUtils >
    Apache BeanUtils > Dozer 

        2、从数据对比结果上看:

        复制效率最快的是 MapStruct , 其原理是 动态的生成对应bean的 getter/setter方法来实现复制; 最慢的是 Dozer 不建议在项目中使用

       

        3、Apache BeanUtils 效率低:

一直提到 Apache BeanUtils 效率低下的问题,综合数据看 和 Spring BeanUtils 效率大概差不多。我这边分别用的版本是: Apache 1.9.1 Spring 5.1.4.RELEASE

        

        4、关于 MapStruct:

GitHub - mapstruct/mapstruct: An annotation processor for generating type-safe bean mappers , 有兴趣自己去研究。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值