JAVA对象拷贝 — Interge转Long?效率比拼

  版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

  本文链接:https://blog.csdn.net/u010697366/article/details/105958516

  收起

  前言

  今天开发中遇到一个小问题。

  因为前期沟通不到位。有同学把一个后台接口(用于获取ES中的商品数据)的id相关字段,都设置成了Interge。而我们公司ID的要求是Long。

  这导致数据后期维护十分不方便。还容易出错,举个例子

  因为泛型擦除所以并不会报错且iidMap真实返回类型是Map。导致调用iidMap.containsKey时用Long型是永远取不到的。

  因为是Dubbo服务已经暴露出去。。。不太好收口。后期会废弃使用新的接口。临时的方案,准备用代理层,进行对象的拷贝。

  那么我们问题就变成如下2个问题

  1:如何选择JAVA Bean的Copy方式

  2:Interge要能自动转化为Long

  先把备的拷贝思路罗列出来

  1. 手工编码

  2. 动态代理

  3. Spring反射

  4. 序列化

  有了思路,那我开搞,顺道学习和复习总结一下JAVA对象的拷贝。

  其中序列化方式,在这里其实是可行的。首先后台的量级不大,操作也方便,也能进行Interge和Long的转换。相对的序列化有明显的性能瓶颈,在大量操作时性能下降的特别快。

  抱着好奇,我们一并探究并验证下手工编码,动态代理,Spring反射具体性能如何?能否转换Interge和Long?

  有了相关的思路,网上也找了一下文章,自己动手实现一下

  具体代码基本结构参考三石雨的文章大家可以看看

  先看运行结果

  5中方式的效率如图所示。

  效率来说:

  手写 > 动态代理 > 反射

  1. ManualCopy: 手动编写,效率最高,能类型转换,代码量多

  2. Cglib:动态代理,效率高,不能进行类型转换

  3. Apache Bean Utils , 反射,比较耗时,能进行类型转换

  4. Spring Bean Utils :反射中等耗时,不能进行类型住哪换

  5. Apache Property Utils : 反射 类型不同,直接报错。

  代码结构

  来看看代码结构。

  Bean 源数据和目标数据(其中id类型不同)

  Process类(策略模式)

  各类CopyMethod

  PerformanceTest 单测类

  依赖

  cglib

  cglib

  3.2.2

  org.springframework

  spring-core

  5.2.5.RELEASE

  commons-beanutils

  commons-beanutils

  1.9.2

  org.springframework

  spring-beans

  5.2.5.RELEASE

  junit

  junit

  Bean

  SourceBean :id为Integer

  package com.lctest.demo.lctrain.JavaBeanCopyTest.TO;

  import com.fasterxml.jackson.annotation.JsonProperty;

  import lombok.Getter;

  import lombok.Setter;

  import java.util.Map;

  /**

  * SourceBean :id为Integer

  *

  * @author xiwen.chen

  * @since 2020-05-06

  */

  @Setter

  @Getter

  public class SourceBean {

  private Integer iid;

  @JsonProperty("gmt_create")

  private Integer gmtCreate;

  private String name;

  @JsonProperty("actor_map")

  private Map actorMap;

  }

  DestBean:对应Source的id 变为 Long型

  package com.lctest.demo.lctrain.JavaBeanCopyTest.TO;

  import com.fasterxml.jackson.annotation.JsonProperty;

  import lombok.Getter;

  import lombok.Setter;

  import java.util.Map;

  /**

  * DestBean:对应Source的id 变为 Long型

  *

  * @author xiwen.chen

  * @since 2020-05-06

  */

  @Setter

  @Getter

  public class DestBean {

  private Long iid;

  @JsonProperty("gmt_create")

  private Long gmtCreate;

  private String name;

  @JsonProperty("actor_map")

  private Map actorMap;

  }

  Process类(策略模式)

  package com.lctest.demo.lctrain.JavaBeanCopyTest;

  import com.lctest.demo.lctrain.JavaBeanCopyTest.TO.DestBean;

  import com.lctest.demo.lctrain.JavaBeanCopyTest.TO.SourceBean;

  /**

  * desc

  *

  * @author xiwen.chen

  * @since 2020-05-06

  */

  public class CopyProcessor {

  private int count;

  public CopyProcessor(int count) {

  this.count = count;

  System.out.println("性能测试=======" + this.count + "===========");

  }

  public void process(CopyMethod methodCallBack, SourceBean sourceBean) throws Exception {

  long processBegin = System.currentTimeMillis();

  DestBean destBean = null;

  System.out.println(methodCallBack.getMethodName() + "测试开始!");

  for (int i = 0; i < count; i++) {

  destBean = methodCallBack.beanCopy(sourceBean);

  }

  long processEnd = System.currentTimeMillis();

  long timeConsuming = processEnd - processBegin;

  System.out.println(methodCallBack.getMethodName() + "测试结束!共耗时" + timeConsuming + "毫秒,copy结果如下:");

  System.out.println(destBean.getName());

  System.out.println(destBean.getIid());

  System.out.println(destBean.getActorMap());

  System.out.println(destBean.getGmtCreate());

  System.out.println("=============================================");

  }

  }

  单测类

  package com.lctest.demo.lctrain.JavaBeanCopyTest;

  import com.lctest.demo.lctrain.JavaBeanCopyTest.TO.SourceBean;

  import com.lctest.demo.lctrain.JavaBeanCopyTest.copymethod.ApacheBeanUtilsCopy;

  import com.lctest.demo.lctrain.JavaBeanCopyTest.copymethod.ApachePropertyUtilsCopy;

  import com.lctest.demo.lctrain.JavaBeanCopyTest.copymethod.CglibCopy;

  import com.lctest.demo.lctrain.JavaBeanCopyTest.copymethod.ManualCopy;

  import com.lctest.demo.lctrain.JavaBeanCopyTest.copymethod.SpringBeanUtilsCopy;

  import org.junit.Before;

  import org.junit.Test;

  import java.util.HashMap;

  import java.util.Map;

  /**

  * desc

  *

  * @author xiwen.chen

  * @since 2020-05-06

  */

  public class PerformanceTest {

  private SourceBean sourceBean = null;

  private ManualCopy manualCopy = null;

  private CglibCopy cglibCopy = null;

  private ApacheBeanUtilsCopy apacheBeanUtilsCopy = null;

  private ApachePropertyUtilsCopy apachePropertyUtilsCopy = null;

  private SpringBeanUtilsCopy springBeanUtilsCopy = null;

  @Before

  public void init() {

  sourceBean = new SourceBean();

  sourceBean.setIid(445939013);

  sourceBean.setGmtCreate(1588694400);

  sourceBean.setName("xiwen copy bean test");

  Map actorName = new HashMap<>();

  actorName.put("name1", "惜文");

  actorName.put("name2", "荣荣");

  actorName.put("name3", "新新");

  sourceBean.setActorMap(actorName);

  manualCopy = new ManualCopy();

  cglibCopy = new CglibCopy();

  apacheBeanUtilsCopy = new ApacheBeanUtilsCopy();

  apachePropertyUtilsCopy = new ApachePropertyUtilsCopy();

  springBeanUtilsCopy = new SpringBeanUtilsCopy();

  }

  @Test

  public void performTest10000() throws Exception {

  CopyProcessor copyProcessor = new CopyProcessor(10000);

  copyProcessor.process(apacheBeanUtilsCopy, sourceBean);

  copyProcessor.process(manualCopy, sourceBean);

  copyProcessor.process(cglibCopy, sourceBean);

  copyProcessor.process(springBeanUtilsCopy, sourceBean);

  copyProcessor.process(apachePropertyUtilsCopy, sourceBean);

  }

  }

  CopyMethod 5个具体实现类

  接口

  package com.lctest.demo.lctrain.JavaBeanCopyTest;

  import com.lctest.demo.lctrain.JavaBeanCopyTest.TO.DestBean;

  import com.lctest.demo.lctrain.JavaBeanCopyTest.TO.SourceBean;

  /**

  * desc

  *

  * @author xiwen.chen

  * @since 2020-05-06

  */

  public interface CopyMethod {

  public String getMethodName();

  public DestBean beanCopy(SourceBean sourceBean) throws Exception;

  }

  实现类

  public class ManualCopy implements CopyMethod {

  @Override

  public String getMethodName() {

  return "manual copy";

  }

  @Override

  public DestBean beanCopy(SourceBean sourceBean) throws Exception {

  DestBean destBean = new DestBean();

  destBean.setActorMap(sourceBean.getActorMap());

  destBean.setGmtCreate(sourceBean.getGmtCreate().longValue());

  destBean.setIid(sourceBean.getIid().longValue());

  destBean.setName(sourceBean.getName());

  return destBean;

  }

  }

  public class SpringBeanUtilsCopy implements CopyMethod {

  @Override

  public String getMethodName() {

  return "Spring Bean Utils";

  }

  @Override

  public DestBean beanCopy(SourceBean sourceBean) throws Exception {

  DestBean destBean = new DestBean();

  BeanUtils.copyProperties(sourceBean, destBean);

  return destBean;

  }

  }

  public class CglibCopy implements CopyMethod {

  private BeanCopier beanCopier = BeanCopier.create(SourceBean.class, DestBean.class, false);

  @Override

  public String getMethodName() {

  return "Cglib BeanCopier";

  }

  @Override

  public DestBean beanCopy(SourceBean sourceBean) throws Exception {

  DestBean destBean = new DestBean();

  beanCopier.copy(sourceBean, destBean, null);

  return destBean;

  }

  }

  public class ApachePropertyUtilsCopy implements CopyMethod {

  @Override

  public String getMethodName() {

  return "Apache Property Utils";

  }

  @Override

  public DestBean beanCopy(SourceBean sourceBean) throws Exception {

  DestBean destBean = new DestBean();

  PropertyUtils.copyProperties(destBean, sourceBean);

  return destBean;

  }

  }

  public class ApacheBeanUtilsCopy implements CopyMethod {

  @Override

  public String getMethodName() {

  return "Apache Bean Utils";

  }

  @Override

  public DestBean beanCopy(SourceBean sourceBean) throws Exception {

  DestBean destBean = new DestBean();

  BeanUtils.copyProperties(destBean, sourceBean);

  return destBean;

  }

  }

  ————————————————

  版权声明:本文为CSDN博主「纸巷」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

  原文链接:https://blog.csdn.net/u010697366/article/details/105958516

 

沈阳看妇科去哪个医院:http://www.23969955.com/

posted @ 2020-05-08 10:54  温水木  阅读(481)  评论(0)    收藏  举报