BeanUtils如何优雅的拷贝List[通俗易懂]

BeanUtils如何优雅的拷贝List[通俗易懂]前言BeanUtils.copyProperties();确实为我们做了很多事情,虽然不能完美完成深拷贝,但是对于po、vo、dto的拷贝已经足够用了。但是其还是有一些不够完美的地方不足:不能拷贝list,而拷贝list的情况又大量存在,因此会有许多重复代码 for(Ssource:sources){Ttarget=newT();…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

目录

一步到位springboot目录
gitee:https://gitee.com/chaitou/leilema.git

前言

BeanUtils.copyProperties();确实为我们做了很多事情,虽然不能完美完成深拷贝,但是对于povodto的拷贝已经足够用了。但是其还是有一些不够完美的地方

不足:

  1. 不能拷贝list,而拷贝list的情况又大量存在,因此会有许多重复代码
		for (S source : sources) { 
   
            T target = new T();
            copyProperties(source, target);
            list.add(target);
        }
  1. 有一些简单的查询,仅仅需要转换一下vo也需要new Vo()
public Vo findById(Integer id) { 
   
	Vo vo = new Vo();
	Po po = dao.findById(id);
	copyProperties(po, vo);
	return vo;
}
  1. 这种拷贝方式是没有返回值的,现在jdk8支持stream()操作之后(参考:Jdk8 Stream),支持不是很友好,不方便lambda表达式的使用

因此我们决定通过集成BeanUtils类,自己造一个方便用的轮子。

使用

我们将新创建一个轮子BeanConvertUtils,使用如下

  1. 当我们要转换povo时,只需要
// 使用前
public Vo findById(Integer id) { 
   
	Vo vo = new Vo();
	Po po = dao.findById(id);
	copyProperties(po, vo);
	return vo;
}

// 使用后
public Vo findById(Integer id) { 
   
	return BeanConvertUtils.converTo(dao.findById(id), Vo::new);
}

// 使用后,通过lambda表达式特殊处理个别字段
public Vo findById(Integer id) { 
   
	return BeanConvertUtils.converTo(dao.findById(id), Vo::new, 
		(s, t) -> t.setName(s.getName))
	);
}
  1. 当我们要拷贝list的时候也很简单
// 使用前
public List<Vo> findAll() { 
   
	List<Vo> vos = new ArrayList();
	List<Po> pos = dao.findAll();
	for (Po po : Pos) { 
   
    	Vo vo = new Vo();
    	BeanUtis.copyProperties(po, vo);
    	vos.add(vo);
    }
	return vos;
}

// 使用后
public List<Vo> findAll() { 
   
	return BeanConvertUtils.converToList(dao.findAll(), Vo::new)
}

// 同样支持自定义lambda
public List<Vo> findAll() { 
   
	return BeanConvertUtils.converToList(dao.findAll(), Vo::new,
		(s, t) -> t.setName(s.getName))
	)
}

代码

/** * 转换对象工具 * * @author bugpool */
public class BeanConvertUtils extends BeanUtils { 
   

    public static <S, T> T convertTo(S source, Supplier<T> targetSupplier) { 
   
        return convertTo(source, targetSupplier, null);
    }

    /** * 转换对象 * * @param source 源对象 * @param targetSupplier 目标对象供应方 * @param callBack 回调方法 * @param <S> 源对象类型 * @param <T> 目标对象类型 * @return 目标对象 */
    public static <S, T> T convertTo(S source, Supplier<T> targetSupplier, ConvertCallBack<S, T> callBack) { 
   
        if (null == source || null == targetSupplier) { 
   
            return null;
        }

        T target = targetSupplier.get();
        copyProperties(source, target);
        if (callBack != null) { 
   
            callBack.callBack(source, target);
        }
        return target;
    }

    public static <S, T> List<T> convertListTo(List<S> sources, Supplier<T> targetSupplier) { 
   
        return convertListTo(sources, targetSupplier, null);
    }

    /** * 转换对象 * * @param sources 源对象list * @param targetSupplier 目标对象供应方 * @param callBack 回调方法 * @param <S> 源对象类型 * @param <T> 目标对象类型 * @return 目标对象list */
    public static <S, T> List<T> convertListTo(List<S> sources, Supplier<T> targetSupplier, ConvertCallBack<S, T> callBack) { 
   
        if (null == sources || null == targetSupplier) { 
   
            return null;
        }

        List<T> list = new ArrayList<>(sources.size());
        for (S source : sources) { 
   
            T target = targetSupplier.get();
            copyProperties(source, target);
            if (callBack != null) { 
   
                callBack.callBack(source, target);
            }
            list.add(target);
        }
        return list;
    }

    /** * 回调接口 * * @param <S> 源对象类型 * @param <T> 目标对象类型 */
    @FunctionalInterface
    public interface ConvertCallBack<S, T> { 
   
        void callBack(S t, T s);
    }
}

性能

由于只是BeanUtils的一个封装,跟原来的代码性能几乎差不多,如果要说差一点也没错,毕竟多了一层函数堆栈的调用,但是基本可以忽略不计。主要的性能还是由BeanUtils决定。

提醒

不知道大家对这个BeanConvertUtils工具类感觉怎么样,自己在项目中倒是大量使用,也很方便。但是有两点要提醒

  1. 此方法依旧不能解决深层次的深拷贝问题,详细的可以google一下BeanUtils的深拷贝问题
  2. 如果source或者targetSupplier只要有一个为null,本工具类不像BeanUtils一样抛出异常,而是返回null,因为笔者认为调用方如果把null进行准换,那就是想转换为null,为不为空应该由调用方自己负责
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/194813.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • jupyter适合开发吗_jupyternotebook和pycharm的区别

    jupyter适合开发吗_jupyternotebook和pycharm的区别JupyterNotebook真的是让人又爱又失望,在有的场景下它极其便利,但是在很多大模型或复杂项目上,它又无能为力。在Jupytext这个项目中,作者希望既能利用Notebook的可视化优势,同时也能利用纯文本编写优势。可以说,是时候联合JupyterNotebook与PyCharm了。Jupytext项目地址:https://github.com/mwouts/jup…

    2022年8月29日
    1
  • 1、排序二叉树「建议收藏」

    1、排序二叉树「建议收藏」2.建立并中序遍历一个排序二叉树排序二叉树是指左子树的所有节点的值均小于它根节点的值,右子树的所有节点的值均大于它根节点的值,如下图是一棵排序二叉树输入:输入有一行,表示若干个要排序的数,输入0时停止输出二叉树的凹入表示和二叉树的中序遍历序列sample:input:567834891235677722570output:     12 …

    2022年7月25日
    7
  • dategrip激活码[最新免费获取]

    (dategrip激活码)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~8…

    2022年3月27日
    67
  • Idea激活码最新教程2019.1.4版本,永久有效激活码,亲测可用,记得收藏

    Idea激活码最新教程2019.1.4版本,永久有效激活码,亲测可用,记得收藏Idea 激活码教程永久有效 2019 1 4 激活码教程 Windows 版永久激活 持续更新 Idea 激活码 2019 1 4 成功激活

    2025年5月24日
    0
  • 软件测试缺陷报告内容_软件测试缺陷分析

    软件测试缺陷报告内容_软件测试缺陷分析1软件缺陷缺陷是一种泛称,它可以指功能的错误,也可以指性能低下,易用性差等 并不是所有的测试人员都能提交被开发认可的缺陷,也不是测试人员在任何时候都能提交被开发认可的缺陷2什么是软件缺陷软件未达到产品说明书标准的功能 软件出现了产品说明书指明不会出现的错误 软件功能超出产品说明书指明范围 软件未达到产品说明书虽未指出但应达到的目标 软件测试员认为软件难以理解,不易使用,运行速度缓慢,或者最终用户认为不好3缺陷产生的原因4发现缺陷用户体验不够好 界面上有明显的错误信

    2022年9月17日
    1
  • Java的三种注释

    Java的三种注释Java基础是java初学者的起点,是帮助你从小白入门到精通必学基础课程!为初学者而著!Java300集>>>适合准备入行开发的零基础员学习Java,基于最新JDK13、IDEA平台讲解的,视频中穿插多个实战项目。每一个知识点都讲解的通俗易懂,由浅入深。不仅适用于零基础的初学者,有经验的程序员也可做巩固学习。配套学习:Java初学者入门教程>>>Java注释:单行、多行和文档注释注释是对程序语言的说明,有助于开发者和用户之间的交流,方便理…

    2022年7月7日
    18

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号