当前位置:首页 > 科技  > 软件

改造BeanUtils,优雅实现List数据拷贝

来源: 责编: 时间:2024-06-12 17:31:02 266观看
导读BeanUtils.copyProperties();确实为我们做了很多事情,虽然不能完美完成深拷贝,但是对于 po、vo、dto 的拷贝已经足够用了。可还是有一些不够完美的地方。不足几点如下:①. 不能拷贝 list,而拷贝 list 的情况又大量存在,因

BeanUtils.copyProperties();确实为我们做了很多事情,虽然不能完美完成深拷贝,但是对于 po、vo、dto 的拷贝已经足够用了。可还是有一些不够完美的地方。O3Q28资讯网——每日最新资讯28at.com

不足几点如下:O3Q28资讯网——每日最新资讯28at.com

①. 不能拷贝 list,而拷贝 list 的情况又大量存在,因此会有许多重复代码。O3Q28资讯网——每日最新资讯28at.com

for (S source : sources) {    T target = new T();    copyProperties(source, target);    list.add(target);}

②. 有一些简单的查询,仅仅需要转换一下 vo 也需要 new Vo()。O3Q28资讯网——每日最新资讯28at.com

public Vo findById(Integer id) { Vo vo = new Vo(); Po po = dao.findById(id); copyProperties(po, vo); return vo;}

③. 这种拷贝方式是没有返回值的,jdk8 支持 stream() 操作之后,支持不是很友好,不方便 lambda 表达式的使用,因此我们决定通过集成 BeanUtils 类,自己造一个方便用的轮子。O3Q28资讯网——每日最新资讯28at.com

使用

我们将新创建一个轮子 BeanConvertUtils,使用如下,当我们要转换 po、vo 时,只需要:O3Q28资讯网——每日最新资讯28at.com

// 使用前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)) );}

当我们要拷贝 list 的时候也很简单:O3Q28资讯网——每日最新资讯28at.com

// 使用前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)}// 同样支持自定义lambdapublic List<Vo> findAll() { return BeanConvertUtils.converToList(dao.findAll(), Vo::new,  (s, t) -> t.setName(s.getName)) )}

代码如下:O3Q28资讯网——每日最新资讯28at.com

/** * 转换对象工具 * */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 决定。O3Q28资讯网——每日最新资讯28at.com

提醒

不知道大家对这个 BeanConvertUtils 工具类感觉怎么样,自己在项目中倒是大量使用,也很方便。O3Q28资讯网——每日最新资讯28at.com

但是有两点要提醒:O3Q28资讯网——每日最新资讯28at.com

  • 此方法依旧不能解决深层次的深拷贝问题,详细的可以 google 一下 BeanUtils 的深拷贝问题。
  • 如果 source 或者 targetSupplier 只要有一个为 null,本工具类不像 BeanUtils 一样抛出异常,而是返回 null,因为笔者认为调用方如果把 null 进行准换,那就是想转换为 null,为不为空应该由调用方自己负责。

本文链接:http://www.28at.com/showinfo-26-93363-0.html改造BeanUtils,优雅实现List数据拷贝

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 什么是测试自动化?意义、方法、方法论、工具和收益

下一篇: 我们一起聊聊JavaScript判断数据为对象

标签:
  • 热门焦点
  • 俄罗斯:将审查iPhone等外国公司设备 保数据安全

    iPhone和特斯拉都属于在各自领域领头羊的品牌,推出的产品也也都是数一数二的,但对于一些国家而言,它们的产品可靠性和安全性还是在限制范围内。近日,俄罗斯联邦通信、信息技术
  • 小米降噪蓝牙耳机Necklace分享:听一首歌 读懂一个故事

    在今天下午的小米Civi 2新品发布会上,小米还带来了一款新的降噪蓝牙耳机Necklace,我们也在发布结束的第一时间给大家带来这款耳机的简单分享。现在大家能见到最多的蓝牙耳机
  • 28个SpringBoot项目中常用注解,日常开发、求职面试不再懵圈

    前言在使用SpringBoot开发中或者在求职面试中都会使用到很多注解或者问到注解相关的知识。本文主要对一些常用的注解进行了总结,同时也会举出具体例子,供大家学习和参考。注解
  • 三言两语说透设计模式的艺术-单例模式

    写在前面单例模式是一种常用的软件设计模式,它所创建的对象只有一个实例,且该实例易于被外界访问。单例对象由于只有一个实例,所以它可以方便地被系统中的其他对象共享,从而减少
  • 量化指标是与非:挽救被量化指标扼杀的技术团队

    作者 | 刘新翠整理 | 徐杰承本文整理自快狗打车技术总监刘新翠在WOT2023大会上的主题分享,更多精彩内容及现场PPT,请关注51CTO技术栈公众号,发消息【WOT2023PPT】即可直接领取
  • .NET 程序的 GDI 句柄泄露的再反思

    一、背景1. 讲故事上个月我写过一篇 如何洞察 C# 程序的 GDI 句柄泄露 文章,当时用的是 GDIView + WinDbg 把问题搞定,前者用来定位泄露资源,后者用来定位泄露代码,后面有朋友反
  • 共享单车的故事讲到哪了?

    来源丨海克财经与共享充电宝相差不多,共享单车已很久没有被国内热点新闻关照到了。除了一再涨价和用户直呼用不起了。近日多家媒体再发报道称,成都、天津、郑州等地多个共享单
  • 品牌洞察丨服务本地,美团直播成效几何?

    来源:17PR7月11日,美团App首页推荐位出现&ldquo;美团直播&rdquo;的固定入口。在直播聚合页面,外卖&ldquo;神枪手&rdquo;直播间、美团旅行直播间、美团买菜直播间等均已上线,同时
  • 荣耀Magic4 至臻版 首创智慧隐私通话 强劲影音系统

    2022年第一季度临近尾声,在该季度内,许多品牌陆续发布自己的最新产品,让大家从全新的角度来了解当今的手机技术。手机是电子设备中,更新迭代十分迅速的一款产品,基
Top