优雅的BeanCopy实现

300 阅读1分钟

起因

很多时候都想应用个功能强大的beancopy, 可以各种的处理,于是就写了一个

说明

这个只是个浅copy, 实际工作中还有DozerBeanMapper写了深copy

代码实现

请大家批评指正,谢谢!

/**
 * Created by songzhaoying on 2020/9/2 20:58.
 *
 * @author songzhaoying@.
 * @date 2020/9/2 20:58.
 */
public class BeanCopy1Util {


    /**
     * List<S> => List<T>
     *
     * @param sourceList: 数据源类
     * @param target:     目标类::new(eg: UserVO::new)
     * @return
     */
    public static <S, T> List<T> copyListBean(Collection<? extends S> sourceList, Supplier<T> target) {
        return copyListBean(sourceList, target, null);
    }


    /**
     * List<S> => List<T>
     * 带回调(可自定义字段拷贝规则)
     *
     * @param sourceList:      数据源类
     * @param target:          目标类::new(eg: UserVO::new)
     * @param callBack:        回调函数
     * @param ignoreProperties
     * @return
     */
    public static <S, T> List<T> copyListBean(Collection<? extends S> sourceList, Supplier<T> target
            , BiConsumer<S, T> callBack, String... ignoreProperties) {
        if (CollectionUtils.isEmpty(sourceList)) {
            return new ArrayList<>(0);
        }
        if (target == null) {
            return new ArrayList<>(0);
        }

        List<T> list = new ArrayList<>(sourceList.size());
        for (S source : sourceList) {
            T t = copyBean(source, target, callBack, ignoreProperties);
            if (t == null) {
                continue;
            }
            list.add(t);
        }
        return list;
    }


    /**
     * S => T
     *
     * @param sourceBean
     * @param target
     * @param callBack
     * @param ignoreProperties
     * @param <S>
     * @param <T>
     * @return
     */
    public static <S, T> T copyBean(S sourceBean, Supplier<T> target
            , BiConsumer<S, T> callBack, String... ignoreProperties) {
        if (target == null) {
            return null;
        }

        T t = target.get();

        return getObjectCopy(sourceBean, t, callBack, ignoreProperties);
    }

    /**
     * 对象copy
     *
     * @param source
     * @param destination
     * @param callBack
     * @param ignoreProperties
     * @param <S>
     * @param <T>
     * @return
     */
    public static <S, T> T getObjectCopy(S source, T destination
            , BiConsumer<S, T> callBack, String[] ignoreProperties) {
        if (source == null || destination == null) {
            return destination;
        }

        BeanUtils.copyProperties(source, destination, ignoreProperties);

        // 回调
        if (callBack != null) {
            // 回调
            callBack.accept(source, destination);
        }

        return destination;
    }


    public static void main(String[] args) {
        List<Person> personList = new ArrayList<>();
        Person person1 = new Person(1, 1, 18, "SongZhaoYing");
        Person person2 = new Person(2, 0, 20, "Lisi");

        personList.add(person1);
        personList.add(person2);

        List<Person> personList1 = copyListBean(personList
                , () -> new Person()
                , (s, t) -> {
                    if (s.getAge() != null && s.getAge() > 18) {
                        System.out.println("这么大了, 成家了吗,该成家了哦!");
                    }
                    t.setSexName(PersonSexEnum.getName(t.getSex()));
                }
                , "id", "name");

        /*
         Person8 private Long id; Person private Integer id;
         属性不一致 不能copy 可以回调处理
         */
        List<Person8> person8List = copyListBean(personList
                , () -> new Person8()
                , (s, t) -> {
                    t.setId(s.getId().longValue());
                }
                , "name");
        System.out.println(person8List);

        Person person = copyBean(person1, () -> new Person(), null);
        // 这样的场景也是有的,自己体会
        BeanCopyUtil.copyBean(person1, () -> person2, null);

        System.out.println(personList1);
    }
}