The elegant use of the List collection operations BeanUtils

Summary

In the sales process, we may often convert data between Entity, Bo, Vo layer data, Entity persistence layer corresponds to the data structure (typically a mapping model database table), Bo is the data structure of the corresponding service layer operations , Vo is the data structure Controller and client interaction. Large part of the property may be the same between these data structures, we will continue to re-assignment when in use.
Such as: client transport layer to the Web administrator, we will use the information AdminVo reception, but when to the Service layer, I need to use AdminBo, this time you need to attribute AdminVo example of an assignment to a AdminBo instance.

BeanUtils

Spring provides org.springframework.beans.BeanUtils class fast assignment, such as:
AdminEntity class

public class AdminEntity{
    private Integer id;
    
    private String password;

    private String username;

    private String userImg;
    .... //一些 Set Get方法
}

AdminVo class, and because the client is dealing, so the password property is not suitable here

public class AdminVo{
    private Integer id;

    private String username;

    private String userImg;
    .... //一些 Set Get方法
}

If we need to AdminEntity instance attribute values ​​to be AdminVo instance (ignore Bo layer, right)

    AdminEntity entity = ...;
    AdminVo vo = new AdminEntity();
    // org.springframework.beans.BeanUtils
    BeanUtils.copyProperties(entity, vo); // 赋值

Then the value of this attribute would AdminVo instance and attribute values AdminEntity the same instance.
But if we are a collection of time it can not be such a direct assignment. Such as:

        List<Admin> adminList = ...;
        List<AdminVo> adminVoList = new ArrayList<>(adminList.size());
        BeanUtils.copyProperties(adminList, adminVoList); // 赋值失败

Such direct assignment is not desirable, as seen from the method name (copyProperties), they will only copy of the property value, then the above-mentioned adminListproperties and adminVoListproperties are not a cent relationship. So how to solve?

A way (to solve the violence, not recommended)

code show as below:

        List<Admin> adminList = ...;
        List<AdminVo> adminVoList = new ArrayList<>(adminList.size());
        for (Admin admin : adminList) {
            AdminVo adminVo = new AdminVo();
            BeanUtils.copyProperties(admin, adminVo);
            adminVoList.add(adminVo);
        }
    return adminVoList;

Although the forcycle can be solved, but that is not elegant, this code will continue to increase, the code is more, it will look out of place to repeat, that's right! Is the forlocal loop assignment, can be optimized away (code written in more than one to look out). Then look elegant way two

Second way (elegant, recommended)

This is my first time to write generic code that could be improved, as follows:
ColaBeanUtils class (Cola is our dog name, ha ha)

import org.springframework.beans.BeanUtils;

public class ColaBeanUtils extends BeanUtils {

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

    /**
     * @author Johnson
     * 使用场景:Entity、Bo、Vo层数据的复制,因为BeanUtils.copyProperties只能给目标对象的属性赋值,却不能在List集合下循环赋值,因此添加该方法
     * 如:List<AdminEntity> 赋值到 List<AdminVo> ,List<AdminVo>中的 AdminVo 属性都会被赋予到值
     * S: 数据源类 ,T: 目标类::new(eg: AdminVo::new)
     */
    public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> target, ColaBeanUtilsCallBack<S, T> callBack) {
        List<T> 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;
    }

ColaBeanUtilsCallBack interfaces, use of lambda expressions comment java8:

@FunctionalInterface
public interface ColaBeanUtilsCallBack<S, T> {

    void callBack(S t, T s);
}

Used as follows:

    List<AdminEntity> adminList = ...;
        return ColaBeanUtils.copyListProperties(adminList, AdminVo::new);

If you do need treatment (correction) in a loop, then use a lambda expression:

        List<Article> adminEntityList = articleMapper.getAllArticle();
        List<ArticleVo> articleVoList = ColaBeanUtils.copyListProperties(adminEntityList , ArticleVo::new, (articleEntity, articleVo) -> {
            // 回调处理
        });
        return articleVoList;

Just do not be too easy! ! !

to sum up

AdminVo::newWith Supplier<T> targetthis I was completely reference "Java core technology Volume Tenth Edition" of Chapter VIII of generics, because before seen little impression, I did not expect today uses. @FunctionalInterfaceThis is java8 of lambdaexpression of class notes, reference java.util.function.Consumerinterface. I did not expect muddle, put before seen knowledge written, stunned, ha ha.
If the code is entirely coincidental. If the generic code as well as areas for improvement, may in the comments below, thank you very much, Thanks ♪ (· ω ·) Techno.

Personal blog URL: https://colablog.cn/

If my articles help to you, I can focus on the public micro-channel number, the first time to share your article

Micro-channel public number

Guess you like

Origin www.cnblogs.com/Johnson-lin/p/12123012.html