在开发中很多地方都需要两个list互相拷,特别是VO,BO,DTO越来越多,以下代码是在spring的BeanUtils的基础上扩展而来的list copy方法,主要可以实现回调处理,如需copy的字段和目标对象字段不一致,或者是需要进行状态转化。
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
/**
* @Description list拷贝工具类
* @ClassName BeanCopyUtil
* @Author Miss You BUG
* @Date 2020/6/19 14:24
* @Version 1.0
*
* 版权声明:本文为CSDN博主「百块富翁-missyouBUG-renkaijiang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
* 原文链接:https://blog.csdn.net/lingyancangqiong/article/details/118539165
*/
public class BeanCopyUtil extends BeanUtils {
/**
*
对象数据的拷贝
*
* @param sources 数据源
* @param target 目标参数类型(eg: UserVo:new)
* @return
* @author Miss You BUG
* @Date 2020/6/19 15:20
*/
public static T copyProperties(S sources, Supplier target) {
T t = target.get();
copyProperties(sources, t);
return t;
}
/**
* 带回调参数的对象数据的拷贝
*
* @param sources 数据源
* @param target 目标参数类型(eg: BeanCopyUtil.copyProperties(user,UserVO:: new, (userDo,userVo) ->{
* * userVo.setSex("1")})
* @return
* @author Miss You BUG
* @Date 2020/6/19 15:20
*/
public static T copyProperties(S sources, Supplier target, BeanCopyUtilCallBack callBack) {
T t = target.get();
copyProperties(sources, t);
if (callBack != null) {
callBack.callBack(sources, t);
}
return t;
}
/**
* 拷贝不为空的字段
* 使用场景:只想把 sources中有值的拷贝到target中,而不把target对应sources中没有值的赋值为null
* 使用 BeanUtils.copyProperties();会全量拷贝,包括null
*
* @param sources 数据源
* @param target 目标
* @param 数据源泛型
* @param 目标泛型
* @return 目标数据
*/
public static T copyNotEmptyProperties(S sources, T target) {
copyProperties(sources, target, getNullPropertyNames(sources));
return target;
}
/**
* 拷贝不为空的字段:带回调参数
* 使用场景:只想把 sources中有值的拷贝到target中,而不把target对应sources中没有值的赋值为null
* 使用 BeanUtils.copyProperties();会全量拷贝,包括null
*
* @param sources 数据源
* @param target 目标
* @param 数据源泛型
* @param 目标泛型
* @return 目标数据
*/
public static T copyNotEmptyProperties(S sources, T target, BeanCopyUtilCallBack callBack) {
copyProperties(sources, target, getNullPropertyNames(sources));
if (callBack != null) {
callBack.callBack(sources, target);
}
return target;
}
/**
* 集合数据的拷贝
*
* @param sources 数据源
* @param target 目标参数类型(eg: UserVo:new)
* @return
* @author Miss You BUG
* @Date 2020/6/19 15:06
*/
public static List copyListProperties(List sources, Supplier target) {
return copyListProperties(sources, target, null);
}
/**
* 带回调参数的集合数据的拷贝
*
* @param sources 数据源类
* @param target 目标类::new (eg: UserVO::new)
* @param callBack 回调函数 eg: BeanCopyUtil.copyListProperties(userLiset,UserVO:: new, (userDo,userVo) ->{
* userVo.setSex("1");
* userVO.setName(userDo.getUserName());
* })
* @return List List
* @author Miss You BUG
* @Date 2020/6/19 15:09
*/
public static List copyListProperties(List sources, Supplier target, BeanCopyUtilCallBack callBack) {
List list = new ArrayList<>(sources.size());
for (S source : sources) {
T t = target.get();
copyProperties(source, t);
list.add(t);
if (callBack != null) {
callBack.callBack(source, t);
}
}
return list;
}
/**
* 获取为空的字段
*/
private static String[] getNullPropertyNames(Object source) {
BeanWrapper src = new BeanWrapperImpl(source);
PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set emptyNames = new HashSet<>();
for (PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null)
emptyNames.add(pd.getName());
}
return emptyNames.toArray(new String[emptyNames.size()]);
}
}
/**
* @Description 默认回调方法
* @ClassName BeanCopyUtilCallBack
* @Author Miss You BUG
* @Date 2020/6/19 14:22
* @Version 1.0
*/
public interface BeanCopyUtilCallBack {
void callBack(S s, T t);
}
org.springframework
spring-beans
5.3.18
compile
import java.util.ArrayList;
import java.util.List;
public class BeanCopyUtilTest {
public static void main(String[] args){
UserDO user1 = new UserDO();
user1.setId(1L);
user1.setName("翠花");
user1.setAge(17);
user1.setAddress("王家村麻油地");
user1.setIsAdult(0);
//无回调copy
UserVO userVO1 = BeanCopyUtil.copyProperties(user1, UserVO::new);
System.out.println("无回调copy:" + userVO1.toString());
//有回调copy
UserVO userVO2 = BeanCopyUtil.copyProperties(user1, UserVO::new,
(userDo, userVo) -> {
userVo.setAddressStr(userDo.getAddress());
userVo.setIsAdult(userDo.getIsAdult()==0?"未成年":"已成年");
});
System.out.println("有回调copy:" + userVO2.toString());
//copy 不为空的字段
UserDO user2 = new UserDO();
user2.setId(2L);
user2.setName("酸菜");
user2.setAddress("李家村油菜田");
UserVO user3 = new UserVO();
user3.setAge(20);
UserVO userVO4 = BeanCopyUtil.copyNotEmptyProperties(user2, user3);
System.out.println("copy 不为空的字段:" + userVO4.toString());
UserVO userVO5 = BeanCopyUtil.copyNotEmptyProperties(user2, user3,
(userDo, userVo) -> {
userVo.setAddressStr(userDo.getAddress());
});
System.out.println("copy 不为空的字段,带回调:" + userVO5.toString());
UserDO user5 = new UserDO();
user5.setId(3L);
user5.setName("奶茶妹妹");
user5.setAddress("赵家村向阳坡");
user5.setAge(18);
user5.setIsAdult(1);
//copy list 不带回调
List userDoList1 = new ArrayList<>(5);
userDoList1.add(user1);
userDoList1.add(user5);
List userVOS1 = BeanCopyUtil.copyListProperties(userDoList1, UserVO::new);
System.out.println("copy list:" + userVOS1);
List userVOS2 = BeanCopyUtil.copyListProperties(userDoList1, UserVO::new,
(userDo, userVo) -> {
userVo.setAddressStr(userDo.getAddress());
userVo.setIsAdult(userDo.getIsAdult()==0?"未成年":"已成年");
});
System.out.println("copy list 带回调:" + userVOS2);
}
}
static class UserVO {
private Long id;
private String name;
private Integer age;
private String addressStr;
private String isAdult;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddressStr() {
return addressStr;
}
public void setAddressStr(String addressStr) {
this.addressStr = addressStr;
}
public String getIsAdult() {
return isAdult;
}
public void setIsAdult(String isAdult) {
this.isAdult = isAdult;
}
@Override
public String toString() {
return "UserVO{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", addressStr='" + (addressStr == null ? "" : addressStr) + '\'' +
", isAdult='" + (isAdult == null ? "" : isAdult) + '\'' +
'}';
}
}
static class UserDO {
private Long id;
private String name;
private Integer age;
private String address;
private int isAdult;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getIsAdult() {
return isAdult;
}
public void setIsAdult(int isAdult) {
this.isAdult = isAdult;
}
@Override
public String toString() {
return "UserDO{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", addressStr='" + (address == null ? "" : address) + '\'' +
", isAdult='"+isAdult + '\'' +
'}';
}
}
}
示例执行结果:
无回调copy:UserVO{id=1, name='翠花', age=17, addressStr='', isAdult=''}
有回调copy:UserVO{id=1, name='翠花', age=17, addressStr='王家村麻油地', isAdult='未成年'}
copy 不为空的字段:UserVO{id=2, name='酸菜', age=20, addressStr='', isAdult=''}
copy 不为空的字段,带回调:UserVO{id=2, name='酸菜', age=20, addressStr='李家村油菜田', isAdult=''}
copy list:[UserVO{id=1, name='翠花', age=17, addressStr='', isAdult=''}, UserVO{id=3, name='奶茶妹妹', age=18, addressStr='', isAdult=''}]
copy list 带回调:[UserVO{id=1, name='翠花', age=17, addressStr='王家村麻油地', isAdult='未成年'}, UserVO{id=3, name='奶茶妹妹', age=18, addressStr='赵家村向阳坡', isAdult='已成年'}]