>>分享Java编程技术,对《Java面向对象编程》等书籍提供技术支持 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 16995 个阅读者 刷新本主题
 * 贴子主题:  Java的对象的拷贝方式集合 回复文章 点赞(0)  收藏  
作者:Jacky    发表时间:2020-11-24 10:44:41     消息  查看  搜索  好友  邮件  复制  引用

    

1. 反射

使用了缺省的方式进行copy。要求源对象和目标对象必须实现getter和setter。进行copy时,内部会缓存缺省对象,以优化性能。

     源码位置:

org.springframework.beans.BeanUtils

public class TestJavaUtils {

    public static void main(String[] args) {
        UserPo userPo=new UserPo();
        userPo.setId(1001L);
        userPo.setName("tom");
        userPo.setAge(12);

        UserDto userDto=new UserDto();
        //源对象:目标对象
        BeanUtils.copyProperties(userPo,userDto);
        System.out.println(userDto);
    }

        @Data
    public static class UserDto{
        private Long id;

        private String name;

        private Integer age;

        private String sex;
    }
    @Data
    public static class UserPo{
        private Long id;

        private String name;

        private Integer age;
    }
}

2. cglib字节码

copy对象时,可以使用CGLib的BeanCopier(其原理是运行时动态生成了用于复制某个类的字节码),其性能比反射框架org.springframework.beans.BeanUtils性能要高。    

/**
* @param source      原始对象
* @param targetClass 拷贝的对象类型
*/

public static < T1,T2 > T2 createCopy(T1 source, Class < T2 > targetClass) {
    if (source == null) {
        throw new RuntimeException("参数异常");
    } else {
        T2 target;
        try {
            target = targetClass.newInstance();
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
        BeanCopier beanCopier = BeanCopier.create(source.getClass(), targetClass, false);
        beanCopier.copy(source, target, null);
        return target;
    }
}

3. get和set的链式拷贝

本质是使用getter和setter的方式进行copy,但是借助了jdk8的链式编程。    

org.springframework.amqp.utils.JavaUtils

源码位置(未引入rabbitMq可以粘贴代码到项目里面):

     源码中使用如下方式进行copy的。    

public final class JavaUtils {

    /**
     * The singleton instance of this utility class.
     */

    public static final JavaUtils INSTANCE = new JavaUtils();

    private JavaUtils() {
        super();
    }

    /**
     * Invoke {@link Consumer#accept(Object)} with the value if the condition is true.
     * @param condition the condition.
     * @param value the value.
     * @param consumer the consumer.
     * @param <T> the value type.
     * @return this.
     */

    public <T> JavaUtils acceptIfCondition(boolean condition, T value, Consumer<T> consumer) {
        if (condition) {
            consumer.accept(value);
        }
        return this;
    }

    /**
     * Invoke {@link Consumer#accept(Object)} with the value if it is not null.
     * @param value the value.
     * @param consumer the consumer.
     * @param <T> the value type.
     * @return this.
     */

    public <T> JavaUtils acceptIfNotNull(T value, Consumer<T> consumer) {
        if (value != null) {
            consumer.accept(value);
        }
        return this;
    }

    /**
     * Invoke {@link Consumer#accept(Object)} with the value if it is not null or empty.
     * @param value the value.
     * @param consumer the consumer.
     * @return this.
     */

    public JavaUtils acceptIfHasText(String value, Consumer<String> consumer) {
        if (StringUtils.hasText(value)) {
            consumer.accept(value);
        }
        return this;
    }

    /**
     * Invoke {@link BiConsumer#accept(Object, Object)} with the arguments if the
     * condition is true.
     * @param condition the condition.
     * @param t1 the first consumer argument
     * @param t2 the second consumer argument
     * @param consumer the consumer.
     * @param <T1> the first argument type.
     * @param <T2> the second argument type.
     * @return this.
     */

    public <T1, T2> JavaUtils acceptIfCondition(boolean condition, T1 t1, T2 t2, BiConsumer<T1, T2> consumer) {
        if (condition) {
            consumer.accept(t1, t2);
        }
        return this;
    }

    /**
     * Invoke {@link BiConsumer#accept(Object, Object)} with the arguments if the t2
     * argument is not null.
     * @param t1 the first argument
     * @param t2 the second consumer argument
     * @param consumer the consumer.
     * @param <T1> the first argument type.
     * @param <T2> the second argument type.
     * @return this.
     */

    public <T1, T2> JavaUtils acceptIfNotNull(T1 t1, T2 t2, BiConsumer<T1, T2> consumer) {
        if (t2 != null) {
            consumer.accept(t1, t2);
        }
        return this;
    }

    /**
     * Invoke {@link BiConsumer#accept(Object, Object)} with the arguments if the value
     * argument is not null or empty.
     * @param t1 the first consumer argument.
     * @param value the second consumer argument
     * @param <T> the first argument type.
     * @param consumer the consumer.
     * @return this.
     */

    public <T> JavaUtils acceptIfHasText(T t1, String value, BiConsumer<T, String> consumer) {
        if (StringUtils.hasText(value)) {
            consumer.accept(t1, value);
        }
        return this;
    }

}

  测试用例:    

public class TestJavaUtils {

    /**
     * 对象的copy链式。
     */

    public static void main(String[] args) {
        UserPo userPo=new UserPo();
        userPo.setId(1001L);
        userPo.setName("tom");
        userPo.setAge(12);

        UserDto userDto=new UserDto();

        JavaUtils.INSTANCE.acceptIfNotNull(userPo.getAge(),userDto::setAge).acceptIfNotNull(userPo.getName(),userDto::setName);

        System.out.println(userDto);
    }

        @Data
    public static class UserDto{
        private Long id;

        private String name;

        private Integer age;

        private String sex;
    }
    @Data
    public static class UserPo{
        private Long id;

        private String name;

        private Integer age;
    }
}

----------------------------
原文链接:https://www.jianshu.com/p/64d37f6e6603

程序猿的技术大观园:www.javathinker.net



[这个贴子最后由 flybird 在 2020-11-24 21:44:18 重新编辑]
  Java面向对象编程-->输入与输出(上)
  JavaWeb开发-->访问数据库(Ⅱ)
  JSP与Hibernate开发-->数据库事务的概念和声明
  Java网络编程-->ServerSocket用法详解
  精通Spring-->计算属性和数据监听
  Vue3开发-->组合(Composition)API
  利用堆栈将中缀表达式转换成后缀表达式
  NIO底层原理
  Java设计模式: 单一职责原则和依赖倒置原则详解
  BST 二叉搜索树
  请求大佬们的帮助
  Java是如何实现自己的SPI机制的?
  Java并发之volatile关键字内存可见性问题
  NoClassDefFoundError和ClassNotFoundException的区别
  Java设计模式:迭代器模式
  java比c++强大之处JVM垃圾收集算法
  Java入门实用代码:获取本机IP地址及主机名
  正则表达式【匹配非字母和数字】
  java Pattern和Matcher详解
  Java中用动态代理实现标准的DataSource数据源连接池
  java零基础入门-面向对象篇 抽象类
  更多...
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。