当前位置:网站首页>改造一下 BeanUtils,优雅的实现 List 数据拷贝
改造一下 BeanUtils,优雅的实现 List 数据拷贝
2022-06-24 20:18:00 【Java精选】
前言
BeanUtils.copyProperties();确实为我们做了很多事情,虽然不能完美完成深拷贝,但是对于po、vo、dto的拷贝已经足够用了。但是其还是有一些不够完美的地方
不足:
1.不能拷贝list,而拷贝list的情况又大量存在,因此会有许多重复代码。
for (S source : sources) {
T target = new T();
copyProperties(source, target);
list.add(target);
}2.有一些简单的查询,仅仅需要转换一下vo也需要new Vo()
public Vo findById(Integer id) {
Vo vo = new Vo();
Po po = dao.findById(id);
copyProperties(po, vo);
return vo;
}3.这种拷贝方式是没有返回值的,现在jdk8支持stream()操作之后(参考:Jdk8 Stream),支持不是很友好,不方便lambda表达式的使用。
因此我们决定通过集成BeanUtils类,自己造一个方便用的轮子。
使用
我们将新创建一个轮子BeanConvertUtils,使用如下:
当我们要转换po、vo时,只需要,另外,公众号Java精选,回复java面试,获取面试题资料。
// 使用前
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的时候也很简单
// 使用前
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);
}
/**
* 转换对象,公众号:Java精选
*
* @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;
}
/**
* 回调接口 公众号:Java精选
*
* @param <S> 源对象类型
* @param <T> 目标对象类型
*/
@FunctionalInterface
public interface ConvertCallBack<S, T> {
void callBack(S t, T s);
}
}性能
由于只是BeanUtils的一个封装,跟原来的代码性能几乎差不多,如果要说差一点也没错,毕竟多了一层函数堆栈的调用,但是基本可以忽略不计。主要的性能还是由BeanUtils决定。
提醒
不知道大家对这个BeanConvertUtils工具类感觉怎么样,自己在项目中倒是大量使用,也很方便。但是有两点要提醒。
此方法依旧不能解决深层次的深拷贝问题,详细的可以google一下
BeanUtils的深拷贝问题;如果source或者
targetSupplier只要有一个为null,本工具类不像BeanUtils一样抛出异常,而是返回null,因为笔者认为调用方如果把null进行准换,那就是想转换为null,为不为空应该由调用方自己负责。
版权声明:本文为CSDN博主「bugpool」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
https://bugpool.blog.csdn.net/article/details/105620681
公众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!
最近有很多人问,有没有读者交流群!加入方式很简单,公众号Java精选,回复“加群”,即可入群!
Java精选面试题(微信小程序):3000+道面试题,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计等,在线随时刷题!
------ 特别推荐 ------
特别推荐:专注分享最前沿的技术与资讯,为弯道超车做好准备及各种开源项目与高效率软件的公众号,「大咖笔记」,专注挖掘好东西,非常值得大家关注。点击下方公众号卡片关注。
文章有帮助的话,点在看,转发吧!
边栏推荐
- 2022年起重机司机(限桥式起重机)考试题库模拟考试平台操作
- Single blind box removal, social blind box and friend blind box program source code
- Jar package merging using Apache ant
- Can communication experiment between C and C
- In the process of enterprise development, I found that a colleague used the select * from where condition for update
- QT (35) - operate excel qxlsx qaxobject
- Network request -volley
- 百公里加速仅5.92秒,威兰达高性能版以高能产品实力领跑
- Text editor for QT project practice - Episode 12
- 2021-02-15
猜你喜欢

2022 crane driver (limited to bridge crane) examination question bank simulated examination platform operation

【微服务|Sentinel】簇点链路|微服务集群环境搭建

QT electronic clock
最新QQ微信域名防红PHP程序源码+强制跳转打开

【微服务|Sentinel】实时监控|RT|吞吐量|并发数|QPS

108页(4万字)未来公寓智能化设计平台项目方案建议书2022版
![[redis realizes seckill business ③] specific implementation of optimistic lock for oversold problem](/img/01/5ec4e5dae1748dce3d5dee33a24b0b.png)
[redis realizes seckill business ③] specific implementation of optimistic lock for oversold problem

Custom animation (simulated win10 loading animation)
![[microservices sentinel] cluster link | microservices cluster environment construction](/img/75/3cc6abf1e72d651b082415db9db46c.png)
[microservices sentinel] cluster link | microservices cluster environment construction

【微服务|Sentinel】Sentinel快速入门|构建镜像|启动控制台
随机推荐
【Redis实现秒杀业务②】超卖问题的解决方案
A small crawler program written by beginners
Golang示例续期锁:Redis+Channel+sync.Mutex
图书馆管理系统代码源码(php+css+js+mysql) 完整的代码源码
Scala trait exercise
Mobile security tool jarsigner
C#和C 的CAN通信实验
打卡smart精灵#1,品牌不缺吸引力,产品本身实力如何?
Text editor for QT project practice - Episode 10
Tiktok wallpaper applet source code
2021-11-07
【Redis实现秒杀业务③】超卖问题之乐观锁具体实现
How to quickly open traffic master for wechat applet
Databinding quick start (still using findviewbyid?)
Previous basic review (link)
Scala template method pattern
In the process of enterprise development, I found that a colleague used the select * from where condition for update
Previous basic review
Source code analysis the problem that fragments cannot be displayed in the custom ViewGroup
Technologie des fenêtres coulissantes en octets dans la couche de transmission